<?php

/**
 * 合同service
 * @author wangwx 2015-5-7
 */

namespace common\services\myhtsq;

use common\entities\common\MyscrmContractEntity;
use common\entities\common\MyscrmOrganizationEntity;
use common\entities\ContractEntity;
use common\entities\myhtsq\ContractApplicationEntity;
use common\entities\myhtsq\ContractDocumentEntity;
use common\entities\myhtsq\DocumentEntity;
use common\entities\myhtsq\MyscrmParttimeBusinessEntity;
use common\models\myhtsq\ContractReceivableModel;
use common\repositories\common\MyscrmAuthorizeRepository;
use common\repositories\myhtsq\ContractEmailContactsRepository;
use common\repositories\myhtsq\InvoiceSummaryRepository;
use common\repositories\outstock\DeliveryProductRepository;
use common\repositories\outstock\OutStockOrderRepository;
use common\services\BaseService;
use common\error\ErrorCode;
use common\models\myhtsq\ContractManageModel;
use common\repositories\myhtsq\ContractManageRepository;
use common\repositories\myhtsq\ContractApplicationRepository;
use common\entities\myhtsq\ContractManageEntity;
use common\repositories\myhtsq\ContractRevenueRepository;
use common\repositories\common\MyscrmContractRepository;
use common\models\myhtsq\ContractRevenueModel;
use common\repositories\myhtsq\InvoiceRepository;
use common\repositories\myhtsq\ContractPaymentRepository;
use common\repositories\common\MyscrmOrganizationRepository;
use common\repositories\common\OrganizationToAuthorizeRepository;
use common\repositories\common\MyscrmApplicationRepository;
use common\repositories\myhtsq\SpecialApprovalAuthorizeRepository;
use common\repositories\myhtsq\ContractPropertyRepository;
use common\repositories\myhtsq\ContractCategoryRepository;
use common\repositories\myhtsq\ContractBigCategoryRepository;
use common\repositories\myhtsq\ContractLittlerCategoryRepository;
use common\repositories\myhtsq\ApplicationInfoRepository;
use common\repositories\myhtsq\ReceivableItemRepository;
use common\repositories\myhtsq\MoneyCategoryItemRepository;
use common\repositories\myhtsq\ErpBusinessUnitRepository;
use common\repositories\myhtsq\BussAccountTypesRepository;
use common\services\common\EmailService;
use common\services\common\MyscrmContractManageService;
use common\services\common\MyscrmContractProjectService;
use common\support\DateTimeHelper;
use common\support\PageParam;
use common\repositories\myhtsq\ErpUserRepository;
use common\repositories\myhtsq\DocumentRepository;
use common\repositories\myhtsq\ContractDocumentRepository;
use common\models\myhtsq\DocumentModel;
use common\models\myhtsq\ContractDocumentModel;
use common\repositories\myhtsq\SignAchievementRepository;
use common\repositories\myhtsq\PaymentAchievementRepository;
use common\repositories\myhtsq\ApplicationPriceRepository;
use common\models\myhtsq\SignAchievementModel;
use common\models\myhtsq\PaymentAchievementModel;
use common\repositories\myhtsq\ContractFlowCodeRepository;
use common\entities\myhtsq\ContractPropertyEntity;
use common\repositories\myhtsq\ContractReceivableRepository;
use common\support\ExcelManage;
use common\repositories\myhtsq\ContractAccountCompanyRepository;
use common\repositories\myhtsq\ContractCompanyRepository;
use common\repositories\myhtsq\InvoicePaymentRepository;
use common\support\LogHelper;
use common\support\OSS;
use common\services\myhtsq\ErpInterfaceService;
use common\repositories\myhtsq\SignDelyAttachementRepository;
use common\repositories\myhtsq\SignDelyRepository;
use common\repositories\myhtsq\ContractBalanceAttachementRepository;
use common\entities\myhtsq\ContractBalanceAttachementEntity;
use common\entities\myhtsq\SignDelyEntity;
use common\entities\myhtsq\SignDelyAttachementEntity;
use common\entities\myhtsq\ContractCompanyEntity;
use common\support\StringHelper;
use common\repositories\myhtsq\ContractPrincipalRepository;
use common\entities\myhtsq\ContractPrincipalEntity;
use PHPExcel_IOFactory;
use yii\base\Exception;
use yii\helpers\ArrayHelper;
use common\repositories\myhtsq\InvoiceBusinessUnitRepository;
use common\repositories\myhtsq\InvoiceReceivableRepository;
use common\repositories\common\ContractNumToAdDrainRepository;
use common\entities\common\MyscrmApplicationEntity;
use common\entities\ConfigEntity;
use common\entities\myhtsq\BussAccountTypesEntity;
use common\repositories\myhtsq\RevenueRecognitionRepository;

use common\services\common\MyscrmContractApplicationService;
use common\entities\common\MyscrmOrganizationToAuthorizeEntity;
use common\repositories\myhtsq\AuthorizationAchievementRepository;
use common\entities\myhtsq\MyscrmContractDistributionAmountEntity;
use common\entities\myhtsq\ContractReceivableEntity;
use common\entities\myhtsq\ContractRevenueEntity;
use yii\log\FileTarget;
use common\models\myhtsq\RevenueRecognitionModel;



use mybackend\controllers\ContractController;

use Yii;

class ContractService extends BaseService
{

    public $_errorLog;
    private static $sheetIndex = 0;

    const REPORT_TYPE_SIGN = 1; //合同签约明细表
    const REPORT_TYPE_PAYMENT = 2; //合同回款明细表
    const REPORT_TYPE_PRODUCT = 3; //签约产品明细表
    const REPORT_TYPE_INCOME = 4; //收入明细表
    const REPORT_TYPE_NO_PAYMENT = 14; //已开票未回款明细表
    const REPORT_TYPE_SIGN_ACHIEVE = 5; //签约业绩明细表
    const REPORT_TYPE_PAYMENT_ACHIEVE = 6; //回款业绩明细表
    const REPORT_TYPE_PAY_ACHIEVE = 7; //交付业绩明细表
    const REPORT_TYPE_RECEIVABLE = 8; //应收款项明细表
    const REPORT_TYPE_PAPER = 9; //纸质合同统计表
    const REPORT_TYPE_NO_UPLOAD = 10; //联营区域未上传标的物明细表
    const REPORT_TYPE_OUT_CONTRACT = 11; //违规合同
    const REPORT_TYPE_SPECIAL_INVOICE = 12; //特批发票
    const REPORT_TYPE_SPECIAL_AUTHORIZE = 13; //特批授权
    const REPORT_TYPE_BAD_DEBT_DETAIL = 15; //坏账明细表
    const REPORT_REVENUE_RECOGNITION = 16; //收入结转表
    const REPORT_PAYMENT_RECEIVABLE = 17; //收入结转表


    //合同性质
    const MY_ZS = '54f8a2b7-fce7-11e4-bed8-00155d02c832';//明源签约-直属
    const MY_LY = '7f828b1b-fce8-11e4-bed8-00155d02c832';//明源签约-联营
    const YK_ZS = '7f83719a-fce8-11e4-bed8-00155d02c832';//云客签约-直属
    const YK_LY = '7f8422d0-fce8-11e4-bed8-00155d02c832';//云客签约-联营
    const LY_YKJS = '7f856e81-fce8-11e4-bed8-00155d02c832';//联营签约-云客结算

    public function __construct($config = [])
    {
        $logConfig = [
            'logFile' => \Yii::$app->getRuntimePath() . '/logs/base/contract.log', // 日志文件路径配置
        ];
        $this->_errorLog = new LogHelper($logConfig);

        parent::__construct($config);
    }

    /**
     * 新建合同
     * @param array $contract 合同基本信息数组
     * @param array $productArr 产品列表数组
     * @param array $principalArr 负责人列表数组
     * @param bool $isComeFromBusinessSystem 是否来自商机系统
     * @modify by zhoud01  2017-7-20 收入金额不可为空
     * @return bool|int
     * @throws \yii\db\Exception
     */
    public function addContract($contract, $productArr, $principalArr, $isComeFromBusinessSystem = false)
    {
        $myscrmContractManageModel = new ContractManageModel();
        $myscrmContractManageModel->setScenario('add');

        //坏味道修复

        $db = ContractEntity::getDb();
        $trans = $db->beginTransaction(); //开启事务
        $myscrmContractManageModel->load($contract, '');
        try {

            if ($myscrmContractManageModel->validate()) {
                //检查合同编号是否已存在,如果存在，重新生成新合同编号 ，保证合同编号唯一
                if ((ContractManageRepository::isExistContractCodeByContractCode($myscrmContractManageModel->contract_code) && !$isComeFromBusinessSystem) || $isComeFromBusinessSystem) {
                    $maxContractFlowCode = ContractFlowCodeRepository::getMaxContractFlowCode();
                    $areaCode = ErpBusinessUnitRepository::getBuCodeByBuguid($myscrmContractManageModel->area_id); //获取区域编码
                    $myscrmContractManageModel->contract_code = ContractFlowCodeRepository::createContractCode($areaCode, $myscrmContractManageModel->customer_code, $maxContractFlowCode, '');
                }

                if($isComeFromBusinessSystem == true && $myscrmContractManageModel->contract_code == $contract['contract_code']){
                    return $this->setAndReturn(__LINE__, '商机系统的合同编号不应与将要写入合同系统的合同编号相同');
                }

                //合同产品成交总额  = 签约总额
                $myscrmContractManageModel->application_deal_amount = $myscrmContractManageModel->sign_amount;

                //处理 合同产品标准总额 = 合同产品标准金额（合同产品标准金额合计）
                $application_amount = 0; //合同产品标准总额 默认值

                if (!empty($productArr) && is_array($productArr)) {
                    foreach ($productArr as $value) {
                        if(isset($value['amount'])){
                            $application_amount = $application_amount + $value['amount'];
                        } else {
                            return $this->setAndReturn(__LINE__, '不存在其中的某一项产品，请核对数据是否对应');
                        }
                    }
                }

                //商机系统过来的合同在新增时不记录录入日期
                if ($isComeFromBusinessSystem == false) {
                    //合同录入时间
                    $myscrmContractManageModel->input_date = date("Y-m-d H:i:s", ContractEntity::getDbNowTimestamp());
                }

                if ($application_amount == 0) {
                    $myscrmContractManageModel->application_deal_discount = 0;
                    $myscrmContractManageModel->contract_deal_discount = 0;
                } else {
                    $myscrmContractManageModel->application_deal_discount = sprintf("%.2f", $myscrmContractManageModel->application_deal_amount / $application_amount); //产品成交折扣=合同产品成交总额/合同产品标准金额
                    $myscrmContractManageModel->contract_deal_discount = sprintf("%.2f", $myscrmContractManageModel->sign_amount / $application_amount);   //合同成交折扣=签约金额/合同产品标准总额
                }
                $myscrmContractManageModel->application_amount = $application_amount; //合同产品标准总额


                if(!empty($myscrmContractManageModel->erp_contract_code) && empty($myscrmContractManageModel->erp_contract_id)){
                    $erp_contract_id = ErpInterfaceService::getErpContractGUID($myscrmContractManageModel->erp_contract_code);
                    Yii::info($erp_contract_id,'channel');
                    if(empty($erp_contract_id)){
                        $trans->rollBack();
                        return $this->setAndReturn('-1','会签合同编号不匹配,请仔细检查','会签合同编号不匹配,请仔细检查');
                    }
                    $myscrmContractManageModel->erp_contract_id = $erp_contract_id;
                }

                $contractManageRepository = new ContractManageRepository();

                try {

                    $contractId = $contractManageRepository->saveContract($myscrmContractManageModel, $isComeFromBusinessSystem); //保存合同基本信息
                    if (empty($contractId)) {
                        $trans->rollBack();

                        return $this->setAndReturn(-1, '新增合同失败');

                    }
                } catch (Exception $e) {
                    Yii::error((string)$e);
                    $trans->rollBack();

                    return $this->setAndReturn(-1, (string)$e);
                }

                ContractApplicationRepository::handleApplicationData($contractId, $productArr); //处理签约产品数据
                ContractFlowCodeRepository::addContractFlowCode($contractId); //新增合同流水表
                //处理签约业绩
                SignAchievementRepository::handleContractSignAchievement('add', $contractId, $myscrmContractManageModel->contract_property_id, $myscrmContractManageModel->area_id, $myscrmContractManageModel->sign_people_id, $myscrmContractManageModel->sign_amount, $myscrmContractManageModel->balance_amount);

                //处理合同负责人
                $this->handlePrincipalInfo($principalArr, $contractId);

                $trans->commit();

                return $contractId;
            } else {
                $trans->rollBack();

                return $this->setAndReturn(-1, $myscrmContractManageModel->getAllFirstErrorMessage());
            }
        } catch (\Exception $e) {
            $trans->rollBack();
            Yii::error((string)$e);
            return $this->setAndReturn(-1, '增加合同出错' . $e->getMessage());
        }
    }

    /**
     * 合同负责人处理
     * @param $principal
     * @param $contractId
     * @return bool
     */
    public function handlePrincipalInfo($principal, $contractId)
    {
        if (!empty($principal) && is_array($principal)) {
            foreach ($principal as $value) {
                if (!isset($value ['__type'])) {
                    $value ['__type'] = 'update';
                }
                switch ($value ['__type']) {
                    case 'delete' :
                        if (!empty($value['principal_id'])) {
                            ContractPrincipalRepository::delPrincipalById($value['principal_id']);
                        }
                        break;
                    case 'add' :
                        $entity = new ContractPrincipalEntity();
                        $entity->load($value, '');
                        $entity->principal_id = StringHelper::uuid();
                        $entity->contract_id = $contractId;
                        if ($entity->validate()) {
                            ContractPrincipalRepository::addPrincipal($entity);
                        }
                        break;
                    case '' :
                    case 'update' :
                        $entity = new ContractPrincipalEntity ();
                        $entity->load($value, '');
                        if ($entity->validate()) {
                            ContractPrincipalRepository::updatePrincipal($entity);
                        }
                        break;
                }
            }
        }
        return true;
    }


    /**
     * 更新合同
     * @param array $contract 合同基本信息数组
     * @param array $productArr 产品列表数组
     * @param array $principalArr 负责人列表数组
     * @modify by zhoud01  2017-7-20 校验如果合同状态为已审核则不修改收入金额(应结算金额) 且收入金额不可为空
     * @return boolean|integer
     */
    public function updateContract($contract, $productArr, $principalArr)
    {
        $contractModel = $this->getContractManageModel($contract['contract_id']); //获取model

        if (empty($contractModel)) {//合同不存在
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_EXISTS);
        }

        //修复坏味道

        $myscrmContractManageModel = new ContractManageModel();
        $myscrmContractManageModel->setScenario('update');

        $myscrmContractManageModel->load($contract, '');
        //更新时，判断input_date是否有值，为空则用当前时间填充，否则不更新
        if ($contractModel->input_date == null || $contractModel->input_date == '') {
            $myscrmContractManageModel->input_date = date('Y-m-d');
            //更新签约业绩的业绩归属时间
            SignAchievementRepository::updateBelongTime($contract['contract_id'], date('Y-m-d'));
        } else {
            if(empty($myscrmContractManageModel->input_date)){
                $myscrmContractManageModel->input_date = $contractModel->input_date;
            }
        }

        $db = ContractEntity::getDb();
        $trans = $db->beginTransaction(); //开启事务

        try {
            if ($myscrmContractManageModel->validate()) {

                //合同产品成交总额  = 租用金额
                $myscrmContractManageModel->application_deal_amount = $myscrmContractManageModel->rent_amount;

                //处理 合同产品标准总额 = 合同产品标准金额（合同产品标准金额合计-不含短信金额）
                $application_amount = 0; //合同产品标准总额 默认值
                if (!empty($productArr) && is_array($productArr)) {
                    foreach ($productArr as $value) {
                        if ($value['authorization_type'] == 0 && intval($value['is_standard']) == 1) {//新加的条件：intval($value['is_standard']) == 1：基本信息页面中的标准产品才会累计，结算页面中的产品不累计
                            $application_amount = $application_amount + $value['amount'];
                        }
                    }
                }

                $myscrmContractManageModel->application_amount = $application_amount; //合同产品标准总额
                if ($application_amount == 0) {
                    $myscrmContractManageModel->application_deal_discount = 0;
                    $myscrmContractManageModel->contract_deal_discount = 0;
                } else {
                    $myscrmContractManageModel->application_deal_discount = sprintf("%.2f", $myscrmContractManageModel->application_deal_amount / $application_amount); //产品成交折扣=合同产品成交总额/合同产品标准金额
                    $myscrmContractManageModel->contract_deal_discount = sprintf("%.2f", $myscrmContractManageModel->sign_amount / $application_amount);   //合同成交折扣=签约金额/合同产品标准总额
                }

                if(!empty($myscrmContractManageModel->erp_contract_code) && empty($myscrmContractManageModel->erp_contract_id)){
                    $erp_contract_id = ErpInterfaceService::getErpContractGUID($myscrmContractManageModel->erp_contract_code);
                    Yii::info($erp_contract_id,'channel');
                    if(empty($erp_contract_id)){
                        $trans->rollBack();
                        return $this->setAndReturn('-1','会签合同编号不匹配,请仔细检查','会签合同编号不匹配,请仔细检查');
                    }
                    $myscrmContractManageModel->erp_contract_id = $erp_contract_id;
                }

                $contractId = ContractManageRepository::updateContract($myscrmContractManageModel);

                //更新收入项编码（收入合同号）
                ContractRevenueRepository::updateIncomeCodeByContractId($contractId, $myscrmContractManageModel->contract_code);

                //处理签约业绩
                SignAchievementRepository::handleContractSignAchievement('update', $contractId, $myscrmContractManageModel->contract_property_id, $myscrmContractManageModel->area_id, $myscrmContractManageModel->sign_people_id);

                //处理合同负责人
                if(! empty($principalArr)){
                    $this->handlePrincipalInfo($principalArr, $contractId);
                }

                if ($contractId === false) {//更新失败
                    $trans->rollBack();

                    return $this->setAndReturn(ErrorCode::ERR_CONTRACT_UPDATE);
                }

                ContractApplicationRepository::handleApplicationData($contractId, $productArr); // 处理签约产品数据

                $trans->commit();

                return $contractId;
            } else {
                $trans->rollBack();

                return $this->setAndReturn(ErrorCode::ERR_CONTRACT_PARAM_INVALID);
            }
        } catch (\Exception $e) {
            $trans->rollBack();

            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_UPDATE);
        }
    }

    /**
     * 获取合同模型
     *
     * @param  $contractId string  合同ID
     * @return array|ContractManageEntity
     */
    public function getContractManageModel($contractId){
        return ContractManageRepository::getContractManageModelByContractId($contractId); //获取model
    }

    /**
     * 获取ERP合同模型
     *
     * @param  $erpContractId string  erp合同ID
     * @return array|ContractManageEntity
     */
    public function getErpContractId($erpContractId){
        return ContractManageRepository::getContractManageByErpContractId($erpContractId); //获取model
    }

    /**
     * 获取主负责人信息
     * @param $contractId
     * @return array
     */
    public function getPrincipalInfo($contractId)
    {
        $principal = ContractPrincipalRepository::getPrincipalListByContractId($contractId);
        if (!empty($principal)) {
            foreach ($principal as &$value) {
                $value['principal_name'] = $this->getUserNameById($value['principal_by']); //获取负责人名称
                $value['principal_department_name'] = $this->getBuNameById($value['principal_department_by']); //获取部门名称
                $value['principal_area_name'] = $this->getBuNameById($value['principal_area_by']); //获取区域名称
            }
        }
        return $principal;
    }

    /**
     * 获取合同基本信息
     * @param string $contractId 合同id
     * @param        array
     */
    public function getContractInfo($contractId)
    {

        $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); //获取model

        if (empty($contractModel)) {//合同不存在
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_EXISTS);
        }

        $data['contract'] = $contractModel->attributes;
        $data['contract']['area_name'] = ErpBusinessUnitRepository::getBunameByBuguid($contractModel->area_id); //区域名称
        $data['contract']['area_code'] = ErpBusinessUnitRepository::getBuCodeByBuguid($contractModel->area_id); //区域code
        $data['contract']['sign_people_name'] = ErpUserRepository::getUserNameByBuguid($contractModel->sign_people_id); //签约人名称
        $data['contract']['company_name'] = ContractCompanyRepository::getContractCompanyNameByCompanyId($contractModel->company_id); //签署公司名称
        $data['contract']['sign_people_department_name'] = $this->getBuNameById($contractModel->sign_people_department_by); //签约人所属部门

        //获取合同负责人
        $data['principal'] = $this->getPrincipalInfo($contractId);

        //获取租期
        $contractInfo = MyscrmContractRepository::getContractByContractNum($contractModel->contract_code); //获取合同表信息


        if (empty($contractInfo)) {
            $data['contract']['beginOn'] = '';
            $data['contract']['endOn'] = '';
        } else {
            $data['contract']['beginOn'] = $contractInfo->BeginOn;
            $data['contract']['endOn'] = $contractInfo->EndOn;
        }

        $data['contract']['littler_category_name'] = ContractLittlerCategoryRepository::getContractLittlerCategoryNameByLittlerCategoryId($contractModel->littler_category_id); //获取小类名称
        $applicationData = ContractApplicationRepository::getStandardContractApplicationByContractId($contractId);
        //处理其他产品的情况 增加相关字段返回

        //TODO 获取合同下广告信息
        $adAmount = 0;
        $adList = $this->getAdOrganizationInfo($contractId);
        foreach ($adList as $v){
            $adAmount += $v['Money'];
        }

        foreach ($applicationData as &$application) {

            if ($application["in_other"] == 1) {
                $application["other_application_id"] = $application["application_id"];
                $application["other_application_name"] = $application["application_name"];
                $application["application_id"] = "other";
                $application["application_name"] = "其他-" . $application["other_application_name"];
            }

            //TODO 获取contract_application_id

            $AuthorizeNum = 0;
            $AuthorizeAmount = 0;

            $contractapplicationId = $application['contract_application_id'];

            $getAuthorizeInfos = OrganizationToAuthorizeRepository::getAuthorizeNumByContractApplicationId($contractapplicationId);

            if(! empty($getAuthorizeInfos)){
                foreach ($getAuthorizeInfos as $getAuthorizeInfo ){
                    $AuthorizeNum += $getAuthorizeInfo['TotalNum'];
                    //TODO 获取结算金额
                    $AuthorizeAmount +=$getAuthorizeInfo['SettlementAmount'];
                    //TODO 获取产品类型(合同类型)
                }
            }


            if($application['application_id'] ==='2802105e-11ac-4191-9fbe-adf1d1945daa'){//广告类型取已经投放的金额

                //坏味道修复

                $AuthorizeNum = $adAmount;
                $application['authorization_numeric'] = (int)$contractModel->rent_amount;
            }

            //TODO 增加已出数目
            $application['alreadyOutNum'] = $AuthorizeNum;

            $application['settlementAmount'] = $AuthorizeAmount;

            //TODO 合同属性
            $application['productType'] = isset($getAuthorizeInfos[0]['ProductType']) ? $getAuthorizeInfos[0]['ProductType'] : '';//取第一条当合同属性即可

            $status = '未开始';//1：初始未开通状态,2:部分开通状态,3完全开通状态

            if((int)$AuthorizeNum <= 0){//已经开通的少于订单数目：未开通状态
                $status = '未开始';
            }

            if( 0 < (int)$AuthorizeNum && $AuthorizeNum < (int)$application['authorization_numeric']){//已经开通的少于订单数目：部分开通状态
                $status = '部分完成';
            }

            //TODO 思考通过租户授权过来的产品如何显示完成状态
            //TODO 思考类似旺财包这样没有数量的产品的完成状态如何表达
            if((int)$AuthorizeNum === (int)$application['authorization_numeric'] ){//完全开通
                if((int)$AuthorizeNum !==0 && (int)$application['authorization_numeric']!==0){
                    $status = '全部完成';
                }
            }

            if((int)$AuthorizeNum > (int)$application['authorization_numeric']){//开通数目超过订单数目
                $status = '超额';
            }


            if($application['application_id'] ==='8486db84-ffc5-4ff7-994d-bfc940d88e46' && $contractModel->contract_status == 2){//广告服务费 已经审核就全部完成
                $status = '全部完成';
                $application['alreadyOutNum'] = 1;//且数量为1
            }

            if($application['delivery_rules'] == 1 ||$application['delivery_rules'] == 2){

                $getAuthorizeInfos = OrganizationToAuthorizeRepository::getAuthorizeNumByContractApplicationId($application['contract_application_id']);
                if($getAuthorizeInfos){
                    $status = '全部完成';
                }

            }

            if($application['application_id'] == '3fe3d587-15b4-40c5-a016-f88d55427727'){//广告的状态

                $getAdInfo = $this->getAdOrganizationInfo($contractId);
                $amount = 0;
                if(!empty($getAdInfo)){
                    foreach ($getAdInfo as $item){
                        $amount +=$item['Money'];
                    }
                }

                $application['alreadyOutNum'] = $amount;

                if($amount == 0){
                    $status = '未开始';
                }

                if($amount>0&&$amount<$application['amount']){
                    $status = '部分完成';
                }

                if($amount==$application['amount']){
                    $status = '全部完成';
                }

                if($amount>$application['amount']){
                    $status = '超额';
                }

            }

            //TODO 增加状态
            $application['status'] = $status;

        }

        //依据合同性质获取和同业务/财务来源
        $data['contract']['from_finance'] = $this->getContractSource($contractModel->contract_property_id)->from_finance;
        $data['contract']['from_performance_finance'] = $this->getContractSource($contractModel->contract_property_id)->from_performance_finance;

        $data['application'] = $this->getShareAmount($data['contract']['application_amount'], $data['contract']['application_deal_amount'], $applicationData);

        return $data;
    }


    /**
     * 云客类合同更新业绩
     * @author zhoud01
     * @since 2017-8-18
     */
    public function actionUpdateAchievementForYk($contractId)
    {
        $contractPropertyId = $this->getContractNature($contractId);

        //TODO 获得产品
        $contractApplication = $this->getContractApplication($contractId);

        //TODO 获得合同下所有基本产品
        $getContractApplication = ContractApplicationRepository::getContractApplicationByContractId($contractId);//合同下基本信息产品

        //TODO 需要获取合同下基本信息
        $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); //获取model
        $income_amount = $contractModel->income_amount;
        $balance_amount = $contractModel->balance_amount;


        //TODO 需要标准总额合计
        $StandardAmountAll = 0;
        foreach ($getContractApplication as $app){
            $StandardAmountAll += $app['amount'];//标准总额合计
        }


        $ykPropertyId = [
            ContractPropertyEntity::MYYK_PROPERTY_DIRECTLY_UNDER_ID,//云客签约-直属
            ContractPropertyEntity::MYYK_PROPERTY_JOINT_OPERATION_ID,//云客签约-联营
            ContractPropertyEntity::MYYK_PROPERTY_DIRECT_SALES_ID,//云客直属
//            '7f83719a-fce8-11e4-bed8-00155d02c832',//云客签约-直属
//            '7f8422d0-fce8-11e4-bed8-00155d02c832',//云客签约-联营
//            'efa353cd-51ca-11e8-a035-00155d02c83e',//云客直属
        ];

        if(in_array($contractPropertyId,$ykPropertyId)){//将产品信息写入业绩表
            //TODO 业绩处理
            foreach ($contractApplication as $item){
                $item['__type'] = 'add';
                $item['contract_nature'] = 'yks';
                $item['standard_amount_all'] = $StandardAmountAll;

                //坏味道修复

                $item['income_amount'] = $income_amount;
                $item['balance_amount'] = $balance_amount;

                //坏味道修复
                $this->addAuthorizationAchievement($item,$contractId);
            }

        }

    }

    public function getContractNature($contractId)
    {
        $info = $this->getContractManageInfo($contractId);
        return $info->contract_property_id;
    }


    /**
     * 获取合同基本信息
     * @param string $contractId 合同id
     * @param        array
     */
    public function getContractNum($contractId)
    {
        $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); //获取model
        return $contractModel->contract_code;

    }


    /**
     * 获取合同id所有签约产品列表
     * @param $contractId
     * @return array|bool
     */
    public function getContractApplicationList($contractId)
    {
        $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); //获取model
        if (empty($contractModel)) {//合同不存在
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_EXISTS);
        }

        $applicationData = ContractApplicationRepository::getAllContractApplicationByContractId($contractId);

        //计算标准总额
        $application_amount = 0;
        foreach ($applicationData as $app) {
            $application_amount = $application_amount + $app['amount'];
        }
        //合同下所有产品标准总额合计,合同结算金额,合同下所有产品
        return $this->getShareAmount($application_amount, $contractModel->balance_amount, $applicationData);
    }


    /**
     * 获取合同id所有签约产品列表
     * @param $contractId
     * @return array|bool
     */
    public function getContractAchievement($contractId)
    {
        $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); //获取model
        if (empty($contractModel)) {//合同不存在
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_EXISTS);
        }

        $applicationData = ContractApplicationRepository::getAllAchievementByContractId($contractId);

        //计算标准总额
        $application_amount = 0;
        foreach ($applicationData as $app) {
            $application_amount = $application_amount + $app['amount'];
        }
        //合同下所有产品标准总额合计,合同结算金额,合同下所有产品
        return $this->getShareAmount($application_amount, $contractModel->balance_amount, $applicationData);
    }



    /**
     * 获取合同id所有签约信息
     * @param $contractId
     * @author zhoud01
     * @return array|bool
     */
    public function getContractManageListByContractId($contractId)
    {
        //坏味道修复
        return ContractManageRepository::getContractManageListByContractId($contractId); //获取model

    }

    /**
     * 根据会签ID找合同
     * @param $signId
     * @author xiazc01
     * @return array|bool
     */
    public function getContractManageBySignId($signId)
    {
        return ContractManageRepository::getContractManageBySignId($signId); //获取model
    }


    /**
     * 获取合同ID所有的标准总额（标准产品以及非标准产品）
     *
     * @param $contractId
     * @return int
     */
    private function __getApplicationAllAmount($contractId)
    {
        $applicationData = ContractApplicationRepository::getAllContractApplicationByContractId($contractId);

        //计算标准总额
        $application_amount = 0;
        foreach ($applicationData as $app) {
            $application_amount = $application_amount + $app['amount'];
        }
        return $application_amount;
    }

    /**
     * 获取产品签约分摊金额
     * 取数公式=标准总额/标准总额合计*产品租金金额
     * @param int $application_sum
     * @param int $deal_amount
     * @param array $data
     * @return array
     */
    private function getShareAmount($application_sum = 0, $deal_amount = 0, $data = [])
    {
        //合同下所有产品标准总额合计,合同结算金额,合同下所有产品
        foreach ($data as &$item) {
            $item["share_amount"] = $this->calculateShareAmount($application_sum, $deal_amount, $item['amount']);
        }

        return $data;
    }

    /**
     * 签约分摊金额=标准总额/标准总额合计*产品租金金额
     * 结算分摊金额=标准总额/标准总额合计*结算金额
     * @param $application_amount
     * @param $application_deal_amount
     * @param $amount
     * @return float|int
     */
    private function calculateShareAmount($application_amount, $application_deal_amount, $amount)
    {
        return $application_amount == 0 ? 0 : round($amount / $application_amount * $application_deal_amount, 2);
    }

    /**
     * 提交复核
     * @param string $contractId 合同id
     * @return boolean
     */
    public function submitReview($contractId)
    {

        $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); //获取model

        if (empty($contractModel)) {//合同不存在
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_EXISTS);
        }
        if ($contractModel->contract_status != ContractManageEntity::APPROVE_STATUS_DRAFT) {//草稿状态，才能提交复核
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_SUBMIT_REVIEW_STATUS);
        }
        //判断是否有产品，没有产品不能提交复核 (非软件租用服务)
        if ($contractModel->littler_category_id != "62f81ca9-fcf4-11e4-bed8-00155d02c832" && !ContractApplicationRepository::isExistContractApplicationByContractId($contractId)) {
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_APPLICATION);
        }

        //云客签约-直属区域/云客签约-联营区域 : 收入金额汇总 = 签约金额
        if ($contractModel->contract_property_id == ContractPropertyEntity::MYYK_PROPERTY_DIRECTLY_UNDER_ID || $contractModel->contract_property_id == ContractPropertyEntity::MYYK_PROPERTY_JOINT_OPERATION_ID || $contractModel->contract_property_id == ContractPropertyEntity::MYYK_PROPERTY_DIRECT_SALES_ID) {
            $amount = $contractModel->sign_amount;
        } else {
            //明源签约-直属区域/明源签约-联营区域 /联营签约-明源结算/联营签约-云客结算:收入金额汇总=结算金额
            $amount = $contractModel->balance_amount;
        }

        $checkArr = [
            ContractPropertyEntity::MYYK_PROPERTY_JOINT_SIGNED_SETTLEMENT_OPERATION_ID,//联营签约-云客结算
            ContractPropertyEntity::MY_PROPERTY_DIRECTLY_OPERATION_ID,//MY_PROPERTY_DIRECTLY_OPERATION_ID
            ContractPropertyEntity::MY_PROPERTY_JOINT_OPERATION_ID,//MY_PROPERTY_JOINT_OPERATION_ID
        ];


        if(!in_array($contractModel->contract_property_id,$checkArr)){

            //1、收入金额校验规则：收入金额汇总 和签约金额/结算金额必须一致

            //2、应收金额校验规则：应收金额汇总 和签约金额/结算金额必须一致
            $contractReceivableSum = ContractReceivableRepository::getReceivableTotalAmountByContractId($contractId); //应收金额汇总

            if ($contractReceivableSum != $amount) {
                return $this->setAndReturn(ErrorCode::ERR_CONTRACT_RECEIVABLE_SUM);
            }

            //3、签约业绩校验规则：签约业绩金额汇总 和签约金额/结算金额必须一致
            $signAchievementAmount = SignAchievementRepository::getSignAchievementSumByContractId($contractId); //签约业绩金额
            if ($signAchievementAmount != $amount) {
                return $this->setAndReturn(ErrorCode::ERR_CONTRACT_SIGN_ACHIEVEMENT_SUM);
            }
        }



        return ContractManageRepository::updateContractStatus($contractId, ContractManageEntity::APPROVE_STATUS_SUBMIT_HANDLE);
    }

    /**
     * 撤销复核
     * @param string $contractId 合同id
     * @return boolean
     */
    public function cancelReview($contractId)
    {
        $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); //获取model
        if (empty($contractModel)) {//合同不存在
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_EXISTS);
        }
        if ($contractModel->contract_status != ContractManageEntity::APPROVE_STATUS_SUBMIT_HANDLE) {//已审核合同不能撤销复核
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_CANCEL_REVIEW_STATUS);
        }

        return ContractManageRepository::updateContractStatus($contractId, ContractManageEntity::APPROVE_STATUS_DRAFT);
    }

    /**
     * 合同复核
     * @param string $contractId 合同id
     * @return boolean
     */
    public function auditReview($contractId)
    {
        $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); //获取model
        if (empty($contractModel)) {//合同不存在
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_EXISTS);
        }
        if ($contractModel->contract_status != ContractManageEntity::APPROVE_STATUS_SUBMIT_HANDLE) {//提交复核状态，才能复核
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_AUDIT_REVIEW_STATUS);
        }
        $contractModel->review_date = ContractEntity::getDbNowDate();
        $contractModel->save();

        ContractManageRepository::updateContractInputDate($contractId); // 更新合同生效日期
        $result = ContractManageRepository::updateContractStatus($contractId, ContractManageEntity::APPROVE_STATUS_PASS);
        if ($this->getErrCode() == ErrorCode::SUCCESS) {
            //复核成功，发送提醒邮件
            //发送业绩信息
            $signAchievements = SignAchievementRepository::getSignAchievementListByContractId($contractId);
            $signer = [];
            foreach ($signAchievements as $key => $item) {
                $belongUser = ErpUserRepository::getUserById($item['belong_by']);
                $erpMgrUser = ErpUserRepository::getUserById($item['manager_by']);
                $parms = ['contractId' => $contractModel->contract_code,
                          'custName' => $contractModel->customer_name,
                          'custFullName' => $contractModel->customer_full_name,
                          'contractAmount' => $contractModel->sign_amount,
                          'signPerformanceAmount' => $item['achievement_amount'],
                          'signDate' => $contractModel->sign_date,
                          'performanceOwner' => $belongUser['UserName'],
                          'erpCustManager' => empty($erpMgrUser) ? '' : $erpMgrUser['UserName']
                ];
                $cc = empty($erpMgrUser) ? [] : [$erpMgrUser['Email'] => $erpMgrUser['UserName']];
                // TODO 正式环境 且 合同性质不为明源直属的合同 才发邮件
                if(YII_ENV_PROD && $contractModel->contract_property_id != ContractPropertyEntity::MY_PROPERTY_DIRECTLY_OPERATION_ID) {
                    $this->sendEmail($item['belong_by'], '【合同管理】合同信息', 'performance', $parms, $cc);
                }
            }
            //发生未关联发票提醒
            $existInvoice = InvoiceRepository::existInvoiceNotRelContract($contractModel->customer_full_name);
            if (!empty($existInvoice)) {
                $parms = [
                    'userName' => '薛维芝',
                    'contractId' => $contractModel->contract_code,
                    'custFullName' => $contractModel->customer_full_name,
                    'signAmount' => $contractModel->sign_amount
                ];
                // TODO 正式环境 且 合同性质不为明源直属的合同 才发邮件
                if(YII_ENV_PROD && $contractModel->contract_property_id != ContractPropertyEntity::MY_PROPERTY_DIRECTLY_OPERATION_ID) {
                    $this->sendMailHandler(['xuewz@mysoft.com.cn' => '薛维芝'], '【合同管理】已开票未关联合同', 'invoiceNoContract', $parms, []);
                }
            }

            //判断是否存在order_code,关联出库流程,回填合同id以及合同号
            if (!empty($contractModel->order_code)) {
                /* @var $outStockOrderRepository OutStockOrderRepository */
                $outStockOrderRepository = \Yii::createObject(OutStockOrderRepository::className());
                $outStockOrderRepository->updateOrderByCode([
                    "contract_id" => $contractModel->contract_id,
                    "contract_code" => $contractModel->contract_code
                ], $contractModel->order_code);
            }
        }

        return $result;
    }

    /**
     * 作废合同
     * @param string $contractId 合同id
     * @return boolean
     */
    public function cancelContract($contractId)
    {
        $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); // 获取model
        if (empty($contractModel)) { // 合同不存在
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_EXISTS);
        }
        if ($contractModel->contract_status == ContractManageEntity::APPROVE_STATUS_PASS) { // 已审核不能作废
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_CANCELLED_APPROVE_STATUS);
        }
        if ($contractModel->is_cancelled == ContractManageEntity::CONTRACT_IS_CANCELLED) { // 已作废,直接返回true
            return true;
        }

        //检查是否存在发票  存在发票不能作废
        if (InvoiceRepository::isExistContractInvoice($contractId)) {
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_EXIST_INVOICE);
        }

        //检查是否关联回款  存在回款不能作废
        if (ContractPaymentRepository::isExistContractPayment($contractId)) {
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_EXIST_PAYMENT);
        }

        return ContractManageRepository::updateContractCancelledStatusByContractId($contractId);
    }

    /**
     * 合同列表
     * @param integer $pageIndex 页码
     * @param integer $pageSize 页条数
     * @param string $sortBy 排序字段
     * @param int $status 合同状态  合同状态:0：草稿,1：提交复核,2：已审核  -1作废
     * @param string $property 合同性质id
     * @param string $sortBy 排序字段
     * @param boolean $sortAsc 是否升序
     * @param string $property 合同性质
     * @param integer $areaId 区域id
     * @param string $keyword 关键字
     * @param string $signPeopleId 签约人ID
     * @param integer $category 合同小类 0：全部,1:云广告服务,2:云客租用服务+云客增值服务
     * @return array
     */
    public function getContractList($pageIndex, $pageSize, $sortBy, $sortAsc, $status, $property, $keyword = '', $areaId = '', $signPeopleId = '', $timeType = 0, $timeStart = '', $timeEnd = '',$category = 0)
    {
        //判断是否设置签署人(当前用户ID+如果是部门负责人还得加上子集)
        $signPeopleIds = $this->getSignPeopleId($signPeopleId);

        //获取应收责任人列表(当前用户ID+如果是部门负责人还得加上子集),
        if (empty($signPeopleIds)) {
            $payeeIds = $signPeopleIds;
        } else {
            $payeeIds = $this->getSignPeopleId("");
        }

        $pageParam = new PageParam($pageIndex, $pageSize, $sortBy, $sortAsc);
        #区域过滤
        $chooseAllArea = false;
        if (empty($areaId)) {
            $areaId = self::filterBusinessUnit(\Yii::$app->user->identity);
            $chooseAllArea = true;
        }
        #截止时间加一天
        if (!empty($timeEnd)) {
            $timeEnd = date("Y-m-d", strtotime("+1 day", strtotime($timeEnd)));
        }

        $data = ContractManageRepository::getContractList($pageParam, $status, $property, $keyword, $areaId, $signPeopleIds, $timeType, $timeStart, $timeEnd, $chooseAllArea, $payeeIds,$category);
        if (empty($data)) {
            return $data;
        }
        foreach ($data['items'] as $key => $val) {

            //获取租期
            $contractInfo = MyscrmContractRepository::getContractByContractNum($val['contract_code']); //获取合同表信息

            if (empty($contractInfo)) {
                $data['items'][$key]['beginOn'] = '';
                $data['items'][$key]['endOn'] = '';
            } else {
                $data['items'][$key]['beginOn'] = $contractInfo->BeginOn;
                $data['items'][$key]['endOn'] = $contractInfo->EndOn;
            }

            $data['items'][$key]['property_name'] = ContractPropertyRepository::getPropertyNameByPropertyId($val['contract_property_id']); //获取性质名称
            $data['items'][$key]['category_name'] = ContractCategoryRepository::getCategoryNameByCategoryId($val ['category_id']); // 获取合同类别名称
            $data ['items'] [$key] ['company_name'] = ContractCompanyRepository::getContractCompanyNameByCompanyId($val['company_id']); // 获取公司名称
            $data ['items'] [$key] ['user_name'] = ErpUserRepository::getUserNameByBuguid($val ['sign_people_id']); // 获取签约人名称
            $data ['items'] [$key] ['area_name'] = ErpBusinessUnitRepository::getBunameByBuguid($val ['area_id']); // 获取区域名称
        }

        return $data;
    }

    /**
     * 判断是否设置签署人
     * @param $signPeopleId
     * @return bool
     * @throws \yii\base\InvalidConfigException
     */
    private function getSignPeopleId($signPeopleId)
    {
        if (!empty($signPeopleId)) {
            return $signPeopleId;
        }
        $userEntity = ErpInterfaceService::getUserByCode(\Yii::$app->user->identity->usercode);
        $isAreaAuthRole = false;
        /** @var  $roleService RoleService */
        $roleService = Yii::createObject(RoleService::className());
        if ($roleService->isAreaAuthRole($userEntity->UserGUID) == 1) {
            $isAreaAuthRole = true;
        }
        //非区域负责人 非总部职能  配置中的用户才会有
        if (!$isAreaAuthRole && $userEntity->BUGUID != '11b11db4-e907-4f1f-8835-b9daab6e1f23' &&
            $userEntity->BUGUID != '6e2a7816-8e27-4b19-9428-628259bd8eda' &&
            !in_array($userEntity->UserGUID, \Yii::$app->params['allAuthUserId'])
        ) {
            //如果当前人员是部门负责人 则将下属人员也返回
            $res = ErpUserRepository::getUserGuidsByDeptmentFzrID($userEntity->UserGUID);
            array_push($res, $userEntity->UserGUID);
            return $res;
        }
        return '';
    }

    /**
     * 导出未结算合同列表
     * @param boolean $property 合同性质
     * @param integer $areaId 区域id
     * @param string $keyword 关键字
     * @param string $beginDate 结算开始时间
     * @param string $endDate 结算结束时间
     * @return array
     */
    public function exportBalanceContractListExecl($property, $keyword, $areaId, $beginDate, $endDate)
    {

        #区域过滤
        if (empty($areaId)) {
            $areaId = self::filterBusinessUnit(\Yii::$app->user->identity);
        }

        $data = ContractManageRepository::getExportBalanceContractListExecl($property, $keyword, $areaId, $beginDate, $endDate);

        $objPHPExcel = new \PHPExcel();
        //设置当前的sheet
        $objPHPExcel->setActiveSheetIndex(0);
        //设置sheet的name
        $objPHPExcel->getActiveSheet()->setTitle('Simple');

        //设置单元格的值
        $objPHPExcel->getActiveSheet()->setCellValue('A1', '合同GUID');

        $objPHPExcel->getActiveSheet()->setCellValue('B1', '客户名称');
        $objPHPExcel->getActiveSheet()->setCellValue('C1', '客户简称');
        $objPHPExcel->getActiveSheet()->setCellValue('D1', '合同编号');
        $objPHPExcel->getActiveSheet()->setCellValue('E1', '合同性质');
        $objPHPExcel->getActiveSheet()->setCellValue('F1', '合同类别');
        $objPHPExcel->getActiveSheet()->setCellValue('G1', '合同签署公司');
        $objPHPExcel->getActiveSheet()->setCellValue('H1', '合同所属区域');
        $objPHPExcel->getActiveSheet()->setCellValue('I1', '签约人');
        $objPHPExcel->getActiveSheet()->setCellValue('J1', '签约日期');
        $objPHPExcel->getActiveSheet()->setCellValue('K1', '签约金额');
        $objPHPExcel->getActiveSheet()->setCellValue('L1', '租用金额');
        $objPHPExcel->getActiveSheet()->setCellValue('M1', '交付金额');
        $objPHPExcel->getActiveSheet()->setCellValue('N1', '回款金额');
        $objPHPExcel->getActiveSheet()->setCellValue('O1', '结算金额');
        $objPHPExcel->getActiveSheet()->setCellValue('P1', '返款金额');
        $objPHPExcel->getActiveSheet()->setCellValue('Q1', '返款状态');
        $objPHPExcel->getActiveSheet()->setCellValue('R1', '返款类型');
        $objPHPExcel->getActiveSheet()->setCellValue('S1', '返款时间');

        if (!empty($data)) {
            $j = 2;
            foreach ($data as $key => $val) {
                $i = 'A';
                $objPHPExcel->getActiveSheet()->setCellValue($i . $j, $val['contract_id']); // 合同GUID
                $i++;
                $objPHPExcel->getActiveSheet()->setCellValue($i . $j, $val['customer_full_name']); //客户名称
                $i++;
                $objPHPExcel->getActiveSheet()->setCellValue($i . $j, $val['customer_name']); //客户简称
                $i++;
                $objPHPExcel->getActiveSheet()->setCellValue($i . $j, $val['contract_code']); //合同编号
                $i++;
                $objPHPExcel->getActiveSheet()->setCellValue($i . $j, ContractPropertyRepository::getPropertyNameByPropertyId($val['contract_property_id'])); //合同性质
                $i++;
                $objPHPExcel->getActiveSheet()->setCellValue($i . $j, ContractCategoryRepository::getCategoryNameByCategoryId($val ['category_id'])); //合同类别
                $i++;
                $objPHPExcel->getActiveSheet()->setCellValue($i . $j, ContractCompanyRepository::getContractCompanyNameByCompanyId($val['company_id'])); //合同签署公司
                $i++;
                $objPHPExcel->getActiveSheet()->setCellValue($i . $j, ErpBusinessUnitRepository::getBunameByBuguid($val ['area_id'])); //合同所属区域
                $i++;
                $objPHPExcel->getActiveSheet()->setCellValue($i . $j, ErpUserRepository::getUserNameByBuguid($val ['sign_people_id'])); //签约人
                $i++;
                $objPHPExcel->getActiveSheet()->setCellValue($i . $j, self::getDateTimeString($val['sign_date'])); //签约日期
                $i++;
                $objPHPExcel->getActiveSheet()->setCellValue($i . $j, $val['sign_amount']); //签约金额
                $i++;
                $objPHPExcel->getActiveSheet()->setCellValue($i . $j, $val['rent_amount']); //租用金额
                $i++;
                $objPHPExcel->getActiveSheet()->setCellValue($i . $j, $val['delivery_amount']); //交付金额
                $i++;
                $objPHPExcel->getActiveSheet()->setCellValue($i . $j, ContractPaymentRepository::getPaymentSumByContractId($val['contract_id'])); //回款金额
                $i++;
                $objPHPExcel->getActiveSheet()->setCellValue($i . $j, $val['balance_amount']); //结算金额
                $i++;
                $objPHPExcel->getActiveSheet()->setCellValue($i . $j, $val['back_amount']); //返款金额
                $i++;
                $objPHPExcel->getActiveSheet()->setCellValue($i . $j, '未返款'); //返款状态
                $i++;
                $objPHPExcel->getActiveSheet()->setCellValue($i . $j, $val['repayment_type'] == 1 ? '现金' : '转预收'); //返款类型
                $i++;
                $objPHPExcel->getActiveSheet()->setCellValue($i . $j, self::getDateTimeString($val['repayment_time'])); //返款时间

                $j++;
            }
        }

        $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setVisible(false); //把合同guid 设置为隐藏列
        $objWriter = new \PHPExcel_Writer_Excel5($objPHPExcel);
        header("Pragma: public");
        header("Expires: 0");
        header("Cache-Control:must-revalidate, post-check=0, pre-check=0");
        header("Content-Type:application/force-download");
        header("Content-Type:application/vnd.ms-execl");
        header("Content-Type:application/octet-stream");
        header("Content-Type:application/download");
        header('Content-Disposition:attachment;filename="合同结算清单' . date("YmdHis") . '.xls"');
        header("Content-Transfer-Encoding:binary");
        $objWriter->save('php://output');
        exit;
    }

    /**
     * 导入结算合同列表
     * @return boolean
     */
    public function importBalanceContractListExecl()
    {
        if (empty($_FILES ['file'])) {
            return $this->setAndReturn(-1, '上传文件不能为空');
        }
        $filename = explode('.', $_FILES ['file'] ['name']);
        if ($filename [1] != 'xls' && $filename [1] != 'xlsx') {
            return $this->setAndReturn(-1, '请上传EXCEL文件');
        }

        $arr = ExcelManage::importDataByFilePath($_FILES['file']['tmp_name'], 0);
        if (!empty($arr) && count($arr) >= 3) {//导入文件行数不能少于3.因为第3行开始是数据
            $db = ContractEntity::getDb();
            $trans = $db->beginTransaction(); //开启事务

            foreach ($arr as $key => $val) {
                if ($key > 1) {//前两行数据，为无关数据
                    $contractId = $val[0];
                    $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); // 获取model
                    if (empty($contractModel)) { // 合同不存在
                        continue;
                    }

                    //返款状态：已返款0|未返款1
                    $balanceStatus = $val[16] == '未返款' ? ContractManageEntity::CONTRACT_NOT_BALANCE_STATUS : ContractManageEntity::CONTRACT_BALANCE_STATUS;
                    $success = ContractManageRepository::handleContractBalanceStatus($contractId, $balanceStatus);

                    //返款类型：现金1|转预收2
                    $repayment_type = $val[17] == '现金' ? 1 : 2;
                    $contractModel->repayment_type = $repayment_type;

                    //返款时间
                    $contractModel->repayment_time = is_numeric($val[18]) ? gmdate('Y-m-d', intval(($val[18] - 25569) * 3600 * 24)) : $val[18];

                    if ($success == false || $contractModel->save() == false) {
                        $trans->rollBack();
                        return $this->setAndReturn(-1, '', '更新失败,合同编号：' . $val[3]);
                    }
                }
            }
            $trans->commit();
        }

        return ['path' => ''];
    }

    /**
     * 导入纸质文档信息
     * @return bool|string
     * @throws \PHPExcel_Reader_Exception
     */
    public function importContractDocsStoreInfoExcel(){
        if (empty($_FILES ['file'])) {
            return $this->setAndReturn(-1, '上传文件不能为空');
        }
        $filename = explode('.', $_FILES ['file'] ['name']);
        if ($filename [1] != 'xls' && $filename [1] != 'xlsx') {
            return $this->setAndReturn(-1, '请上传EXCEL文件');
        }
        $ext = $filename[1];
        $filePath = $_FILES['file']['tmp_name'];
        ini_set('max_execution_time', 5 * 60);    //超时设置5分钟
        if ($ext == 'xlsx') {
            $readerType = 'Excel2007';
        } else {
            $readerType = 'Excel5';
        }
        $reader = PHPExcel_IOFactory::createReader($readerType); //设置以Excel5格式(Excel97-2003工作簿)
        $PHPExcel = $reader->load($filePath); // 载入excel
        $sheet = $PHPExcel->getSheet(0); // 读取第一個工作表
        $highestRow = $sheet->getHighestRow(); // 取得总行数
        $highestColumn = $sheet->getHighestColumn(); // 取得总列数

        //循环读取每个单元格的数据
        $disableRows = 1;  //不需要处理的行数，第1行不需要处理
        $k = 0;
        $errorRow = [];

        $db = ContractEntity::getDb();
        $trans = $db->beginTransaction(); //开启事务
        //导入字段
        //合同所属区域	客户简称	签约客户全称	签约人	合同编号	签约金额	录入日期	文件类型	文档类型(原件或复印件) 纸质合同归档日期	纸质合同存放位置	保管人	所属文件夹名称
        for ($row = 1 + $disableRows; $row <= $highestRow; $row++) {   //行数是以第2行开始
            $rowValueData = [];
            for ($column = 'A'; $column <= $highestColumn; $column++) { //列数是以A列开始
                $value = trim($sheet->getCell($column . $row)->getValue());
                $rowValueData[] = $value;  //得到一行数据
            }
            $k++;
            $rowValueData[9] = date('Y-m-d', \PHPExcel_Shared_Date::ExcelToPHP($rowValueData[9]));  //日期格式特别处理
            $contractDocument = new ContractDocumentModel();
            $afterData = $contractDocument->processImportData($rowValueData);
            if (in_array(null, $afterData, true)) {
                $errorRow[] = $k;
                continue;
            }

            $contractDocument->setScenario('add');
            $contractDocument->load($afterData, '');
            if ($contractDocument->validate()) {
                ContractDocumentRepository::addContractDocument($contractDocument); // 新增合同文档信息
            }
            $invoiceModel = null;
        }

        $errorCount = count($errorRow);
        $successCount = $k - $errorCount;

        if ($errorCount > 0) {
            $trans->rollBack();
            $result = "导入失败";
            $result .= ',其中第' . implode('、', $errorRow) . '行数据有误';
        }else{
            $result = "成功导入{$successCount}条，失败{$errorCount}条";
            $trans->commit();
        }
        return $result;
    }

    /**
     * 获取结算合同列表
     * @param integer $pageIndex 页码
     * @param integer $pageSize 页条数
     * @param string $sortBy 排序字段
     * @param int $status 结算状态 0：未结算 1：已结算
     * @param string $property 合同性质id
     * @param string $sortBy 排序字段
     * @param boolean $sortAsc 是否升序
     * @param integer $areaId 区域id
     * @param string $keyword 关键字
     * @param string $beginDate 结算开始时间
     * @param string $endDate 结算结束时间
     */
    public function getBalanceContractList($pageIndex, $pageSize, $sortBy, $sortAsc, $status, $property, $keyword, $areaId, $beginDate, $endDate)
    {
        $pageParam = new PageParam($pageIndex, $pageSize, $sortBy, $sortAsc);
        #区域过滤
        if (empty($areaId)) {
            $areaId = self::filterBusinessUnit(\Yii::$app->user->identity);
        }
        $data = ContractManageRepository::getBalanceContractList($pageParam, $status, $property, $keyword, $areaId, $beginDate, $endDate);
        if (empty($data)) {
            return $data;
        }
        foreach ($data['items'] as $key => $val) {

            //获取租期
            $contractInfo = MyscrmContractRepository::getContractByContractNum($val['contract_code']); //获取合同表信息

            if (empty($contractInfo)) {
                $data['items'][$key]['beginOn'] = '';
                $data['items'][$key]['endOn'] = '';
            } else {
                $data['items'][$key]['beginOn'] = $contractInfo->BeginOn;
                $data['items'][$key]['endOn'] = $contractInfo->EndOn;
            }

            $data['items'][$key]['property_name'] = ContractPropertyRepository::getPropertyNameByPropertyId($val['contract_property_id']); //获取性质名称
            $data['items'][$key]['category_name'] = ContractCategoryRepository::getCategoryNameByCategoryId($val['category_id']); //获取合同类别名称
            $data['items'][$key]['company_name'] = ContractCompanyRepository::getContractCompanyNameByCompanyId($val['company_id']); // 获取公司名称
            $data['items'][$key]['user_name'] = ErpUserRepository::getUserNameByBuguid($val['sign_people_id']); //获取签约人名称
            $data['items'][$key]['area_name'] = ErpBusinessUnitRepository::getBunameByBuguid($val['area_id']); //获取区域名称
        }

        return $data;
    }

    /**
     * 判断用户是否过滤所属区域数据
     * @param $user
     * @return false:不需要过滤，BUGUID：公司ID
     */
    public static function filterBusinessUnit($user)
    {
        $userEntity = ErpInterfaceService::getUserByCode($user->usercode);
        #属于明源集团、总部职能、付小玲用户，显示全部区域数据
        if ($userEntity->BUGUID == '11b11db4-e907-4f1f-8835-b9daab6e1f23' ||
            $userEntity->BUGUID == '6e2a7816-8e27-4b19-9428-628259bd8eda' ||
            in_array($userEntity->UserGUID, \Yii::$app->params['allAuthUserId'])
        ) {
            return '';
        }
        $buGUIDList = [];
        $parttimeBUGUIDs = MyscrmParttimeBusinessEntity::find()->where(['user_guid' => $userEntity->UserGUID])->all();
        foreach ($parttimeBUGUIDs as $k => $v) {
            $buGUIDList = array_merge($buGUIDList, ErpInterfaceService::getSubBuGuidsByBuGuid($v->bu_guid));
        }
        return array_merge($buGUIDList, ErpInterfaceService::getSubBuGuidsByBuGuid($userEntity->BUGUID));
    }

    /**
     * 获取合同城市区域列表
     * @return array
     */
    public function getContractAreaList()
    {
        $buGuid = self::filterBusinessUnit(\Yii::$app->user->identity);
        $areaIdList = ContractManageRepository::getContractAreaIdList($buGuid);
        if (empty($areaIdList)) {
            return [];
        }
        $data = [];
        foreach ($areaIdList as $key => $val) {
            $areaName = ErpBusinessUnitRepository::getBunameByBuguid($val->area_id); //获取区域公司名称
            if (!empty($areaName)) {
                $data1['areaId'] = $val->area_id;
                $data1['areaName'] = $areaName;
                array_push($data, $data1);
            }
        }

        return $data;
    }

    /**
     * XML 转数组
     * @authr zhoud01
     * @since 2017-10-20
     * @param string $xml
     */
    public static function xmlToArray($xml){

        //禁止引用外部xml实体

        libxml_disable_entity_loader(true);

        $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);

        $val = json_decode(json_encode($xmlstring),true);

        return $val;

    }

    /**
     * 获取合同收入信息
     * @param string $contractId 合同id
     * @return array
     */
    public function getContractRevenue($contractId)
    {
        $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); // 获取model
        if (empty($contractModel)) { // 合同不存在
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_EXISTS);
        }
        //获取租期
        $contractInfo = MyscrmContractRepository::getContractByContractNum($contractModel->contract_code); //获取合同表信息

        $data['account_company_id'] = $contractModel->account_company_id;
        $data['revenueList'] = ContractRevenueRepository::getContractRevenueListByContractId($contractId);
        $data['contractInfo'] = $contractInfo;

        //获取租期信息
        if (empty($contractInfo)) {
            $data['beginOn'] = '';
            $data['endOn'] = '';
        } else {
            $data['beginOn'] = $contractInfo->BeginOn;
            $data['endOn'] = $contractInfo->EndOn;
        }

        //兼容处理如果表中没有该数据就拿原逻辑的权益日期
        foreach ($data['revenueList'] as &$item){
            $recognition = RevenueRecognitionRepository::getRevenueRecognitionListByRevenueId($item['revenue_id']);
            $item['begin_on'] = empty($item['begin_on'])?$data['beginOn']:$item['begin_on'];
            $item['end_on'] = empty($item['end_on'])?$data['endOn']:$item['end_on'];
            $item['establish_time'] = empty($item['establish_time'])?$contractInfo->EstablishTime:$item['establish_time'];
            $recognitions = RevenueRecognitionRepository::getRevenueRecognitionListByRevenueId($item['revenue_id']);
            $recognitionsAmount = self::summaryRecognitionsAmount($recognitions);
            $item['total_recognition_amount'] = $recognitionsAmount;
            $item['unrecognized_amount'] = $item['amount'] - $recognitionsAmount;
            $item['is_carry_over'] = empty($recognition)?false:true;
        }

        return $data;
    }


    public function getContractRevenueByRevenueId($revenueId,$contractId)
    {
        $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); // 获取model
        if (empty($contractModel)) { // 合同不存在
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_EXISTS);
        }
        //获取租期
        $contractInfo = MyscrmContractRepository::getContractByContractNum($contractModel->contract_code); //获取合同表信息

        $data['revenueList'] = ContractRevenueRepository::getContractRevenueListByRevenueId($revenueId);
        foreach ($data['revenueList'] as &$item){
            $item['begin_on'] = empty($item['begin_on'])?$data['beginOn']:$item['begin_on'];
            $item['end_on'] = empty($item['end_on'])?$data['endOn']:$item['end_on'];
            $item['establish_time'] = empty($item['establish_time'])?$contractInfo->EstablishTime:$item['establish_time'];
            $recognitions = RevenueRecognitionRepository::getRevenueRecognitionListByRevenueId($item['revenue_id']);
            $recognitionsAmount = self::summaryRecognitionsAmount($recognitions);
            $item['total_recognition_amount'] = $recognitionsAmount;
            $item['unrecognized_amount'] = $item['amount'] - $recognitionsAmount;
        }

        return $data;
    }

    private static function summaryRecognitionsAmount($records){

        $receivableAmount = 0;
        foreach ($records as $record){
            $receivableAmount += $record['recognition_amount'];
        }

        return $receivableAmount;

    }

    /**
     * 处理保存收入信息数据
     * @param string $contractId 合同id
     * @param string $accountCompanyId 帐套公司id
     * @param array $revenueArr
     * @return boolean
     */
    public function submitRevenue($contractId, $accountCompanyId, $revenueArr)
    {

        $recognitionList = RevenueRecognitionRepository::getRevenueRecognitionListByRevenueId($revenueArr[0]["revenue_id"]);

        if (!empty($recognitionList)) {//收入已经结转不可修改收入金额
            $revenueArr[0]["recognition_status"] = "recognized";
            //改成前端提示后端已经保证无法修改了
            //$this->setAndReturn(ErrorCode::ERR_REVENUE_EXIST_RECOGNITION,'收入已结转不可调整收入金额');
        }

        if (empty($accountCompanyId)) {//帐套公司不能为空
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_COMPANY);
        }
        if (empty($revenueArr)) {//收入信息不能为空
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_REVENUE);
        }

        $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); // 获取model
        if (empty($contractModel)) { // 合同不存在
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_EXISTS);
        }

        $contractModel->account_company_id = $accountCompanyId;
        $contractModel->save(); //更新。暂不作成功与否处理
        $revenueIds = array();
        foreach ($revenueArr as $val) {
            if (!isset($val['__type'])) {
                $val['__type'] = 'update';
            }

            switch ($val['__type']) {
                case 'add':
                case '':
                    $contractRevenueModel = new ContractRevenueModel(); //增加场景
                    $contractRevenueModel->setScenario('add');
                    $contractRevenueModel->load($val, '');
                    $manageEntity = ContractManageRepository::getContractManageModelByContractId($contractId);
                    $manageEntity->inc = $manageEntity->inc == 0 ? 1 : ++$manageEntity->inc;
                    $num = $manageEntity->inc;
                    $num < 10 && $num = "0" . $num;
                    $contractRevenueModel->income_code = $contractModel->contract_code . "-SR-" . $num; // 生成收入项编码
                    if ($contractRevenueModel->validate()) {
                        $old_income_code = $val['old_income_code'];
                        $revenueId = ContractRevenueRepository::addContractRevenueRecord($contractRevenueModel, $contractId,$old_income_code); //新增收入
                        $revenueIds[] = $revenueId;
                    }else{
                        return self::setAndReturn(__LINE__,$contractRevenueModel->getAllFirstErrorMessage(),$contractRevenueModel->getAllFirstErrorMessage());
                    }
                    if($revenueId && empty($data['parent_id'])){
                        $manageEntity->save();
                    }
                    break;
                case 'update':
                    $contractRevenueModel = new ContractRevenueModel(); //更新场景
                    $contractRevenueModel->setScenario('update');
                    $contractRevenueModel->load($val, '');
                    if ($contractRevenueModel->validate()) {
                        $revenueId = ContractRevenueRepository::updateContractRevenueRecord($contractRevenueModel); //更改收入
                        $revenueIds[] = $revenueId;
                    }else{
                        return self::setAndReturn(__LINE__,$contractRevenueModel->getAllFirstErrorMessage(),$contractRevenueModel->getAllFirstErrorMessage());
                    }
                    break;
                case 'delete':
                    ContractRevenueRepository::deleteContractRevenueByRevenueId($val['revenue_id']); //删除收入
                    break;
            }
        }

        return $revenueIds;
    }

    /**
     * 通过新增/修改开通信息更新收入款
     * @param $arr
     * @param $contractId
     * @param string $contractType
     * @param $revenue
     * @param array|false $author_info
     * @param array|false $myscrm_contract
     * @return bool
     * @throws \Exception
     * @throws \yii\db\Exception
     */
    public function submitRevenueByEstablish($arr,$contractId,$contractType='',$revenue = [],$myscrm_contract = [],$author_info = [])
    {
        if(empty($arr)){
            return true;//空是初次
        }

        $accountCompanyId = '08b070c4-0069-11e5-bed8-00155d02c832'; //明源云客

        // 开启事务
        $configDataBase = ContractEntity::getDb();
        $trans = $configDataBase->beginTransaction();

        try{
            //TODO 记录套账公司
            $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); // 获取model
            $contractModel->account_company_id = $accountCompanyId;
            $resultAdd = $contractModel->save(); //更新。暂不作成功与否处理

            if($resultAdd === false){
                $trans->rollBack();
                return self::setAndReturn(ContractRevenueRepository::getErrCode());
            }


            if(empty($revenue)){
                //TODO 0.合同中编辑套账公司id 1.在合同中增加自赠数inc 2.生成收入项编码 3.新增收入信息
                foreach ($arr as $key=>$val) {

                    //1.在合同中增加自赠数inc
                    $manageEntity = ContractManageRepository::getContractManageModelByContractId($contractId);
                    $manageEntity->inc = $manageEntity->inc == 0 ? 1 : ++$manageEntity->inc;

                    //2.生成收入项编码
                    $num = $manageEntity->inc;
                    $num < 10 && $num = "0" . $num;
                    $arr[$key]['income_code'] = $contractModel->contract_code . "-SR-" . $num; // 生成收入项编码
                    $resultAdd = $manageEntity->save();

                    if($resultAdd === false){//有一次出现失败就表示失败了

                        $trans->rollBack();
                        return self::setAndReturn(ContractRevenueRepository::getErrCode());
                    }
                }
            }

            //3.新增收入信息
//            if($revenue){
//                $resultAdd = ContractRevenueRepository::updateContractRevenueByRedFlush($arr,$contractId,$contractType,$revenue);
//            }else{
                $resultAdd = ContractRevenueRepository::updateContractRevenueRecordByEstablish($arr,$contractId,$contractType,$myscrm_contract,$author_info); //新增收入
//            }
            if($resultAdd === false){
                $trans->rollBack();
                return self::setAndReturn(ContractRevenueRepository::getErrCode());
            }

            $trans->commit();
            return true;
        }catch(Exception $e){
            $trans->rollBack();
            return self::setAndReturn(ErrorCode::ERR_CONTRACT_RECEIVABLE_FORM_VERIFY_FAIL);
        }

    }


    /**
     * 保存结算与返款信息
     * @param array $data 提交合同返款数据
     * @return boolean
     */
    public function updateContractAccount($data)
    {

        //坏味道修复

        //获取合同性质 修改方法
        $contractPropertyId = $this->getContractNature($data['contract_id']);

        //先删后插
        $trans = ContractEntity::getDb()->beginTransaction();
        try {

            $contractModel = ContractManageRepository::getContractManageModelByContractId($data['contract_id']); // 获取model
            if (empty($contractModel)) { // 合同不存在
                return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_EXISTS);
            }

            //坏味道修复

            $contractModel->balance_type = $data['balance_type']; //结算类型 0：标准结算 1：特价结算 2：特批其他
            $contractModel->balance_rate = $data['balance_rate']; //结算比例
            $contractModel->balance_amount = $data['balance_amount']; //结算金额
            $contractModel->back_amount = $data['back_amount']; //返款金额
            $contractModel->balance_remark = $data['balance_remark']; //结算备注
            $contractModel->balance_date = $data['balance_date']; //返款日期
            $contractModel->balance_status = $data['balance_status']; //返款状态
            $contractModel->repayment_type = $data['repayment_type']; //返款类型
            $contractModel->repayment_time = $data['repayment_time']; //返款时间
            $contractModel->repayment_company = $data['repayment_company']; //服务机构
            $contractModel->project_numeric = $data["project_numeric"];//项目数

            $saveResult = $contractModel->save();
            if ($saveResult === false) {
                $trans->rollBack();
                return $this->setAndReturn(__LINE__, '保存合同失败');
            }

            //处理签约业绩
            SignAchievementRepository::handleContractSignAchievement('update', $data['contract_id'], $contractModel->contract_property_id, $contractModel->area_id, $contractModel->sign_people_id);

            //处理附件
            if (isset($data['files']) && is_array($data['files'])) {
                foreach ($data['files'] as $value) {
                    if (!isset($value ['__type'])) {
                        $value ['__type'] = 'update';
                    }
                    switch ($value ['__type']) {
                        case 'delete' :
                            ContractBalanceAttachementRepository::delAttachementById($value['attachement_id']);
                            break;
                        case 'add' :
                            $contractBalanceAttachement = new ContractBalanceAttachementEntity();
                            $contractBalanceAttachement->setAttributes($value);
                            $explode = explode('.', $value['attachement_name']);
                            $extName = end($explode);
                            $contractBalanceAttachement->attachement_ext_name = $extName;
                            $contractBalanceAttachement->contract_id = $data['contract_id'];
                            if ($contractBalanceAttachement->validate()) {
                                ContractBalanceAttachementRepository::addAttachement($contractBalanceAttachement);
                            }
                            break;
                    }
                }
            }

            $trans->commit();
        } catch (\Exception $e) {
            $trans->rollBack();
            return $this->setAndReturn(__LINE__, $e->getMessage());
        }

        return true;
    }

    public function saveDistributionAmount($contractId, $inputDate, $distribution)
    {
        //校验回款分摊金额是否相等
        //合同全部的回款数据

        //处理签约分摊金额
        $trans = ContractEntity::getDb()->beginTransaction();
        try {
            //先删后插
            $deleteResult = $this->deleteDistributionByContractId($contractId);
            if ($deleteResult === false) {
                $trans->rollBack();
                return $this->setAndReturn(__LINE__, '删除签约分摊金额失败');
            }

            $addResult = $this->addDistributionByContractId($contractId, $inputDate, $distribution);
            if ($addResult === false) {
                $trans->rollBack();
                return $this->setAndReturn(__LINE__, '添加签约分摊金额失败');
            }

            $trans->commit();
        } catch (\Exception $e) {
            $trans->rollBack();
            Yii::error($e->getMessage());
            return $this->setAndReturn(__LINE__, $e->getMessage());
        }

        return true;
    }


    public function saveDistributionAmountByAuthorize($contractId, $inputDate, $distribution)
    {

        //处理签约分摊金额
        $trans = ContractEntity::getDb()->beginTransaction();
        try {
            //先删后插
            $deleteResult = $this->deleteDistributionByContractId($contractId);

            if ($deleteResult === false) {
                $trans->rollBack();
                return $this->setAndReturn(__LINE__, '删除签约分摊金额失败');
            }

            $addResult = $this->addDistributionByContractId($contractId, $inputDate, $distribution);
            if ($addResult === false) {
                $trans->rollBack();
                return $this->setAndReturn(__LINE__, '添加签约分摊金额失败');
            }

            $trans->commit();
        } catch (\Exception $e) {
            $trans->rollBack();
            Yii::error($e->getMessage());
            return $this->setAndReturn(__LINE__, $e->getMessage());
        }

        return true;
    }


    public function deleteDistributionByContractId($contractId)
    {
        return ContractManageRepository::deleteDistributionByContractId($contractId);
    }

    public function addDistributionByContractId($contractId, $inputDate, $distributionData)
    {

        foreach ($distributionData as $distribution) {
            $addResult = ContractManageRepository::addDistribution($contractId, $inputDate, $distribution);
            if ($addResult === false) {
                return false;
            }
        }

        return true;
    }

    /**
     * 获取签约分摊金额、结算分摊金额、回款分摊金额列表
     * @param $contractId
     * @return array|\yii\db\ActiveRecord[]
     */
    public function getDistributionAmount($contractId)
    {
        if (empty($contractId)) {
            $this->setAndReturn(__LINE__, '合同ID不能为空');
        }

        //TODO 某种合同逻辑是否需要维护表数据
        //每次请求列表都需要维护分摊金额
        //坏味道修复

        /** @var ErpUserRepository $erpUserRepository */
        $erpUserRepository = \Yii::createObject(ErpUserRepository::className());

        $distributionArr = ContractManageRepository::getDistributionByContractId($contractId);

        //TODO 不是要以数据源显示分组数据,而是要分组好的数据插入到业绩表所以动作在增加开通信息

        //坏味道修复

        foreach ($distributionArr as &$distribution) {
            //填充归属人名称、区域名称、部门名称
            $userEntity = $erpUserRepository->getUserById($distribution['user_id']);
            $erpBusinessUnitEntityForArea = $erpUserRepository->getErpBusinessUnitByBuguid($distribution['area_id']);
            $erpBusinessUnitEntityForDep = $erpUserRepository->getErpBusinessUnitByBuguid($distribution['department_id']);

            $userName = isset($userEntity->UserName) ? $userEntity->UserName : '';
            $areaName = isset($erpBusinessUnitEntityForArea->BUName) ? $erpBusinessUnitEntityForArea->BUName : '';
            $departmentName = isset($erpBusinessUnitEntityForDep->BUName) ? $erpBusinessUnitEntityForDep->BUName : '';

            $distribution['user_name'] = $userName;
            $distribution['area_name'] = $areaName;
            $distribution['department_name'] = $departmentName;
        }

        return $distributionArr;
    }

    /**
     * 获取结算与返款信息数据
     * @param string $contractId 合同Id
     * @return \common\entities\myhtsq\ContractManageEntity
     */
    public function getContractBalanceInfo($contractId)
    {
        $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); // 获取model
        if (empty($contractModel)) { // 合同不存在
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_EXISTS);
        }

        // 附件
        $data = $contractModel->toArray();
        $data['attachement'] = ContractBalanceAttachementRepository::getAttachementListByContractId($contractId);
        return $data;
    }



    /**
     * 获取合同开通信息
     * @param string $contractId 合同id
     * @modify by zhoud01 2017-7-20 ApplicationId 提供给合同基本信息中产品对比用
     * @return array
     */
    public function getContractOrganizationInfo($contractId,$getType = false)
    {

        $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); // 获取model

        if (empty($contractModel)) { // 合同不存在
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_EXISTS);
        }

        ///配置库中获取合同信息 依据合同编号,因此有可能配置库中合同id！=合同库中合同id
        $contractInfos = MyscrmContractRepository::getAllContractByContractNum($contractModel->contract_code); //获取合同表信息
        //租户信息
        $rentInfo = RentInterfaceService::getOrganizationInfo($contractModel->contract_code);

        if(!empty($rentInfo)){
            $data['organizationId'] = $rentInfo['organizationId'];
            $data['uniqueName'] = $rentInfo['uniqueName'];
            $data['friendlyName'] = $rentInfo['friendlyName'];
        }else{
            $data['organizationId'] = '';
            $data['uniqueName'] = '';
            $data['friendlyName'] = '';
        }

        if (empty($contractInfos)) {
            return [];
        }


        //租期信息取第一个授权
        //依据合同获取租户id
        $data["beginOn"] = $contractInfos[0]->BeginOn;
        $data["endOn"] = $contractInfos[0]->EndOn;

        $organizationId = $contractInfos[0]->OrganizationId;
        $data['organizationId'] = $contractInfos[0]->OrganizationId;
        //通过租户id获取租户信息
        //$organizationInfo = MyscrmOrganizationRepository::getById($organizationId);

        //如果myscrm_contract表中的的organizationId在租户表中找不到表示是手动新增的

        /*if (!empty($organizationInfo)) {
            $data['uniqueName'] = $organizationInfo->UniqueName; //企业号
            $data['friendlyName'] = $organizationInfo->FriendlyName; //企业名称
        } else {
            $data['uniqueName'] = ''; //企业号
            $data['friendlyName'] = ''; //企业名称
        }*/

        //TODO 判断产品来源是租户管理系统的还是合同订单系统  TODO 不能以UniqueName 做判断因为有好多都没
        $getTenantAuthorizeProductDatas = self::getTenantAuthorizeProductDatas();
        $UniqueName = array_column($getTenantAuthorizeProductDatas, 'UniqueName');

        $data['AuthorizeList'] = [];

        $arr = [];
        //一个合同对应多个授权 方便按时间分类
        foreach ($contractInfos as $contractInfo) {

            $organizationId = $contractInfo->OrganizationId;
            //授权列表
            $authorizeList = OrganizationToAuthorizeRepository::getAuthorizeListByOrganizationId($organizationId, $contractInfo->ContractId);
            //$organizationInfo = MyscrmOrganizationRepository::getById($organizationId);

            $generation = '';

            if(empty($organizationInfo)){//通过判断是否有租户信息确定是否为自动
                $generation = '手动增加开通产品';
            }else{
                $generation = '自动增加开通产品';
            }

            if (empty($authorizeList)) {
                $authorizeList = [];
            } else {
                $authorize = [];
                foreach ($authorizeList as $key => $value) {
                    $authorize[$key]["beginOn"] = $contractInfo->BeginOn;
                    $authorize[$key]["endOn"] = $contractInfo->EndOn;
                    $authorize[$key]['establishTime'] = $contractInfo->EstablishTime;
                    $authorize[$key]['performanceAccountingTime'] = $contractInfo->PerformanceAccountingTime;
                    $authorize[$key]['contractType'] = $contractInfo->ContractType;

                    $authorize[$key]['totalNum'] = $value->TotalNum; //授权总数
                    $applicationInfo = MyscrmApplicationRepository::getApplicationByApplicationId($value->ApplicationId);//租户中心产品
                    $applicationInfoAtContractDB = MyscrmContractApplicationService::getApplicationInfoByApplicationId($value->ApplicationId);//所有产品
//                    $contractAndApp = ContractApplicationRepository::getContractApplicationAppId($value->ContractApplicationId);//已开产品的信息

                    $FriendlyName = $applicationInfo->FriendlyName;
                    $application_name = $applicationInfoAtContractDB['application_name'];

                    ///TODO 统一名称
//                    $appDataInfo = MyscrmContractApplicationService::getApplicationInfoByAuthorizeUniqueName($applicationInfo->UniqueName,$value->IsQdAdvanced);//查真名用

                    //TODO 通过CPI 取appid
                    $contractAndApp = ContractApplicationRepository::getContractApplicationAppId($value->ContractApplicationId);//订单产品信息
                    $applicationInfoAtContractDB = MyscrmContractApplicationService::getApplicationInfoByApplicationId($contractAndApp->application_id);//所有产品

                    if(!empty($FriendlyName)) {

                        //坏味道修复

                        $authorize[$key]['applicationName'] = $applicationInfoAtContractDB['application_name'];

                        //坏味道修复

                        if(empty($applicationInfoAtContractDB['application_name'])){
                            $authorize[$key]['applicationName'] = $FriendlyName;
                        }
                    }

                    if(!empty($application_name)){
                        $authorize[$key]['applicationName'] = $application_name;
                    }

                    if(empty($FriendlyName) && empty($application_name)){
                        $authorize[$key]['applicationName'] = '';
                    }

                    //TODO 增加 ApplicationId 提供给合同基本信息中产品对比用 by zhoud01 2017-07-20
                    $authorize[$key]['Id'] = $value->Id;//回传给前端的唯一值,判断给那条记录修改 授权主键id
                    $authorize[$key]['ApplicationId'] = $value->ApplicationId;
                    $authorize[$key]['ContractApplicationId'] = $value->ContractApplicationId;
                    $authorize[$key]['OrganizationId'] = $organizationId;
                    $authorize[$key]['contract_code'] = $contractModel->contract_code;
                    $authorize[$key]['ContractId'] = $contractInfo->ContractId;
                    $authorize[$key]['UniqueName'] = $applicationInfo->UniqueName;

                    $authorize[$key]['StandardAmount'] = $contractAndApp->amount;
                    $authorize[$key]['StandardPrice'] = $contractAndApp->price;
                    $authorize[$key]['SettlementType'] = $contractAndApp->settlement_type;
                    $authorize[$key]['SettlementScale'] = $contractAndApp->settlement_scale;
                    $authorize[$key]['Discount'] = $contractAndApp->discount;
                    $authorize[$key]['RealApplicationId'] = $contractAndApp->application_id;
                    $authorize[$key]['OrderCode'] = $contractInfo->order_code;
                    $authorize[$key]['OrderGUID'] = $contractInfo->order_guid;

                    $ErpProducts = [];
                    if($contractInfo && $contractInfo->order_guid){
                        $ErpProducts = Yii::$app->cache->get($contractInfo->order_guid);
                        if(!$ErpProducts){
                            $ErpProducts = ErpInterfaceService::getErpProductInfo($contractInfo->order_guid);
                            //缓存出库单产品信息
                            Yii::$app->cache->set($contractInfo->order_guid,$ErpProducts,86400*2);
                        }
                        Yii::info(var_export($ErpProducts,true),'delivery_order_product_info');
                    }

                    //TODO 在表里增加一个字段标识是修改还是新增 IsModify
                    $authorize[$key]['SettlementAmount'] = $value->SettlementAmount;
                    $authorize[$key]['SignAmount'] = $value->SignAmount;
                    //比例
                    $authorize[$key]['current_discount'] = $contractAndApp->current_discount;
                    $authorize[$key]['area_discount'] = $contractAndApp->area_discount;
                    $authorize[$key]['current_real_discount'] = $contractAndApp->current_real_discount;
                    $authorize[$key]['contract_type'] = $contractAndApp->contract_type;
                    $authorize[$key]['benchmark_amount'] = $contractAndApp->price;
                    $authorize[$key]['rent_period'] = $contractAndApp->rent_period;
                    $authorize[$key]['authorization_numeric'] = $contractAndApp->authorization_numeric;
                    $authorize[$key]['delivery_rules'] = $applicationInfoAtContractDB['delivery_rules'];
                    //匹配erp出库单中的产品信息，找出对应产品的结算金额
                    if($ErpProducts){
                        foreach ($ErpProducts as $erp_product){
                            if($erp_product['Product_Info_Id'] == $contractAndApp->application_id && ContractApplicationRepository::$strToSignTypeMap[$erp_product['CloudSignType']] == $contractAndApp->contract_type && $erp_product['Quantity'] == $value->TotalNum && $contractAndApp->rent_period == $erp_product['Rent_Time']){
                                $authorize[$key]['SettlementAmount'] = $erp_product['Settlement_Amount'];
                                $authorize[$key]['benchmark_amount'] = (isset($erp_product['BenchmarkPrice']) && $erp_product['BenchmarkPrice'])?$erp_product['BenchmarkPrice']:$applicationInfoAtContractDB['price'];
                                $authorize[$key]['area_discount'] = $erp_product['Qyzk']*100;
                                $authorize[$key]['current_real_discount'] = $erp_product['DcSjzk']*100;
                                $authorize[$key]['current_discount'] = $erp_product['DcYhzk']*100;
                                $authorize[$key]['rent_period'] == $erp_product['Rent_Time'];
                                break;
                            }
                        }
                    }
                    $authorize[$key]['buss_type_id'] = $applicationInfoAtContractDB['buss_type_id'];

                    /*if($value->IsModify == 2){//被改过的采用自定义结算金额
                        $authorize[$key]['SettlementAmount'] = $value->SettlementAmount;
                    }*/

                    $authorize[$key]['ProductType'] = $value->ProductType;//应该叫产品属性
                    //TODO 如果是自动的产品则取合同属性里的
                    $authorize[$key]['generation'] =  $generation;//应该叫产品属性

                    if(in_array($applicationInfo->UniqueName,$UniqueName)){//判断如果appid在 myscrm_application_info 中找得到,表示为自动否则为手动 因为空也会在这里找不到
                        $authorize[$key]['isManual'] = 2;//自动2
                        $authorize[$key]['ProductType'] = $contractInfo->ContractType;//应该叫产品属性
                    }else{
                        $authorize[$key]['isManual'] = 1;//手动1
                    }

                }
                $authorizeList = $authorize;
            }

            $arr = array_merge($arr, $authorizeList);
            if (!empty($authorizeList)) {
                $data['AuthorizeList'] = array_merge($data['AuthorizeList'], $authorizeList);
            }
        }

        if($getType){//給业绩信息看的
            return $arr;
        }

        $data['specialAuthorize'] = SpecialApprovalAuthorizeRepository::getSpecialApprovalAuthorizeByContractCode($contractModel->contract_code);

        return $data;
    }

    /**
     * @sine 2017-10-12
     * @auth zhoud01@mingyuanyun.com
     * 判断收入是否被推送
     */
    public function revenueIsSend($contractId)
    {
        $revenueList = $this->getContractRevenue($contractId)['revenueList'];

        $editable = true;
        foreach ($revenueList as $item){
            if($item['state'] === 1 ||$item['state'] === 2){//如果有收入中有已经结转或者推送的
                $editable = false;
                continue;
            }
        }

        return $editable;
    }

    /**
     * @sine 2017-10-26
     * @auth zhoud01@mingyuanyun.com
     * 依据租期和开通时间获取收入状态
     */
    public function getRevenueByTime($contractId,$beginOn,$endOn,$establishTime)
    {
        return ContractRevenueRepository::getContractRevenueByTime($contractId,$beginOn,$endOn,$establishTime);

    }

    /**
     * @param $contractId
     * @param $beginOn
     * @param $endOn
     * @param $establishTime
     * @param $revenue_type
     * @return array
     */
    public function getRevenueBy($contractId,$beginOn,$endOn,$establishTime,$revenue_type){
        return ContractRevenueRepository::getContractRevenueBy($contractId,$beginOn,$endOn,$establishTime,$revenue_type);
    }


    /**
     * @sine 2017-8-09
     * @auth zhoud01@mingyuanyun.com
     * 新增业绩信息
     */
    public function addAuthorizationAchievement($arr,$contract=null)
    {
        return AuthorizationAchievementRepository::addAuthorizationAchievement($arr,$contract);
    }

    /**
     * @sine 2017-8-09
     * @auth zhoud01@mingyuanyun.com
     * 删除业绩信息
     */
    public function deleteAllByContractId($contractId)
    {
        return AuthorizationAchievementRepository::deleteAllByContractId($contractId);
    }

    /**
     * @sine 2017-8-09
     * @auth zhoud01@mingyuanyun.com
     * 获取业绩信息
     */
    public function getAuthorizationAchievementByContractId($contractId)
    {
        return AuthorizationAchievementRepository::getAuthorizationAchievementByContractId($contractId);

    }


    /**
     * @sine 2017-8-30
     * @auth zhoud01@mingyuanyun.com
     * 获取业绩信息
     */
    public function getAuthorizationAchievementByAuthorId($authorId)
    {
        return AuthorizationAchievementRepository::getAuthorizationAchievementByAuthorId($authorId);

    }


    /**
     * @sine 2017-8-09
     * @auth zhoud01@mingyuanyun.com
     * 获取产品单价
     */
    public function getAppPrice($application_id)
    {
        return ApplicationPriceRepository::getAllApplicationPriceByApplicationId($application_id);
    }

    /**
     * @sine 2017-10-12
     * @auth zhoud01@mingyuanyun.com
     * 判断是否为云客类合同
     */

    public function isYkContract($contractId)
    {
        $ykPropertyId = [
            ContractPropertyEntity::MYYK_PROPERTY_DIRECTLY_UNDER_ID,//云客签约-直属
            ContractPropertyEntity::MYYK_PROPERTY_JOINT_OPERATION_ID,//云客签约-直属区域
            ContractPropertyEntity::MYYK_PROPERTY_DIRECT_SALES_ID,//云客直销
        ];

        //获取合同性质
        $contractPropertyId = $this->getContractNature($contractId);

        return in_array($contractPropertyId,$ykPropertyId);
    }

    /**
     * @sine 2017-7-23
     * @auth zhoud01@mingyuanyun.com
     * 新增合同开通信息
     */
    public function addAuthorizeByOrganizationId($arr)
    {
        //查询该产品是否有buss_type_id
        $ApplicationInfo = $this->GetApplicationInfoByApplicationId($arr['application_id']);
        if(!empty($ApplicationInfo)&&empty($ApplicationInfo['buss_type_id'])){//结果取且非空是为了对应从开通信息过来产品修改时是租户过来的产品
            $Msg = $ApplicationInfo['application_name'].':<br />业务收入项字段值为0或者为空';
            return self::setAndReturn(__LINE__,$Msg);
        }

        $this->putLog('zhouding00=>'.json_encode($arr),__METHOD__,true);
        //TODO 将记录一个和信息到配置库合同表用于保存开始和结束时间
        $contractInfos = MyscrmContractRepository::getAllContractByContractNum($arr['contract_num']); //获取合同表信息如果有相同合同编号

        //取租户号
        $organizationId = $contractInfos[0]->OrganizationId;
        $arr['organization_id']=$organizationId;// 配置库合同 ContractId & 租户id => 决定

        $ykPropertyId = [
            ContractPropertyEntity::MYYK_PROPERTY_JOINT_SIGNED_SETTLEMENT_OPERATION_ID,//明源签约-直属
            ContractPropertyEntity::MY_PROPERTY_DIRECTLY_OPERATION_ID,//明源签约-联营
            ContractPropertyEntity::MY_PROPERTY_JOINT_OPERATION_ID,//联营签约-云客结算
        ];

        //获取合同性质
        $contractPropertyId = $this->getContractNature($arr['contract_id']);
        $arr['is_joint'] = in_array($contractPropertyId,$ykPropertyId);
        if(!empty($arr['id'])){// 如果有id表示为修改

            $AuthorInfo = MyscrmOrganizationToAuthorizeEntity::find()->where(['Id'=>$arr['id']])->asArray()->one();
            $arr['ContractId'] = $AuthorInfo['ContractId'];

            // 开启事务
            $configDataBase = ConfigEntity::getDb();
            $trans = $configDataBase->beginTransaction();
            try {

                if(!empty($arr['openType'])&&$arr['openType'] === 'Manual'){//unique_name 为空表示通过授权中心修改
                    //TODO 事物补充
                    $editContractResult =  MyscrmContractRepository::addContract($arr);//修改授权汇总 1

                    if (empty($editContractResult)) {

                        $trans->rollBack();
                        return self::setAndReturn(__LINE__,'授权contract修改失败');
                    }

                    $editAuthorResult =  OrganizationToAuthorizeRepository::addAuthorizeByOrganizationId($arr);//修改授权 2

                    if (empty($editAuthorResult)) {

                        $trans->rollBack();
                        return self::setAndReturn(__LINE__,'授权organizationtoauthorize修改失败');
                    }
                }

                if(in_array($contractPropertyId,$ykPropertyId)) {//将产品信息写入业绩表

                    //TODO 业绩处理 联营的结算分摊直接取出库单里的结算金额
                    $arr['settlement_amount'] = isset($arr['erp_product_settlement_amount'])?$arr['erp_product_settlement_amount']:$arr['settlement_amount'];
                    $editAuthorResult = $this->achievementHandle($arr,'edit');//3

                    if (empty($editAuthorResult)) {

                        $trans->rollBack();
                        return self::setAndReturn(__LINE__,'业绩修改失败');
                    }

                    //TODO 业绩分组
                    $editAuthorResult = $this->achievementGrouping($arr['contract_id']);//4

                    if (empty($editAuthorResult)) {

                        $trans->rollBack();
                        return self::setAndReturn(__LINE__,'修改业绩分组失败');
                    }

                    //TODO 回款处理
                    $editAuthorResult = $this->paymentAverageHandle($arr);//5

                    if (empty($editAuthorResult)) {

                        $trans->rollBack();
                        return self::setAndReturn(__LINE__,'修改回款维护失败');
                    }
                }

                $trans->commit();
            }catch (\Exception $e){
                $trans->rollBack();
                return self::setAndReturn(__LINE__, (string) $e);
            }

            return true;

        }

        // 开启事务  租户中心走这里
        $configDataBase = ConfigEntity::getDb();
        $trans = $configDataBase->beginTransaction();

        try {

                //TODO 需要增加字段表明合同是通过开通信息生成的,需要记录合同属性和结算金额
                $addContractResult =  MyscrmContractRepository::addContract($arr); //获取合同表信息1

                $arr['contractId']=$addContractResult;//通过合同id绑定合同与授权的关系

                if (empty($addContractResult)) {

                    $trans->rollBack();
                    return self::setAndReturn(__LINE__,'授权contract新增失败');
                }

                $addAuthorResult = OrganizationToAuthorizeRepository::addAuthorizeByOrganizationId($arr);//2

                $arr['settlement_average_amount'] = $addAuthorResult['SettlementAmount'];//获取结算分摊金
                $arr['AuthorId'] = $addAuthorResult['AuthorId'];//记录授权id方便通过授权修改  //租户中心需要从别处拿

                if (empty($addAuthorResult)) {

                    $trans->rollBack();
                    return self::setAndReturn(__LINE__,'授权organizationtoauthorize新增失败');
                }

            //TODO 将云建创建好的产品修改其结算金额

            //坏味道修复

            if(in_array($contractPropertyId,$ykPropertyId)) {//将产品信息写入业绩表

                //TODO 需要判断租户中心过来的请求是修改还是新增
                $type = empty($arr['handleType'])?'add':$arr['handleType'];

                //坏味道修复

                $arr['settlement_from_tenant'] = isset($arr['erp_product_settlement_amount'])?$arr['erp_product_settlement_amount']:MyscrmOrganizationToAuthorizeEntity::calculationSettlementAmount($arr);
                //TODO 业绩处理
                $addAuthorResult = $this->achievementHandle($arr,$type);//3

                //坏味道修复

                $this->putLog('achievementHandle=>'.$addAuthorResult,__METHOD__,$addAuthorResult);

                if (empty($addAuthorResult)) {

                    $trans->rollBack();
                    return self::setAndReturn(__LINE__,'业绩新增失败');
                }


                //TODO 业绩分摊处理
                $addAuthorResult = $this->achievementGrouping($arr['contract_id']);//4

                $this->putLog('achievementGrouping=>'.$addAuthorResult,__METHOD__,$addAuthorResult);

                if (empty($addAuthorResult)) {

                    $trans->rollBack();
                    return self::setAndReturn(__LINE__,'新增业绩分组失败');
                }

                $addAuthorResult = $this->paymentAverageHandle($arr);//5

                $this->putLog('paymentAverageHandle=>'.$addAuthorResult,__METHOD__,$addAuthorResult);

                //TODO 回款处理
                if (empty($addAuthorResult)) {

                    $trans->rollBack();
                    return self::setAndReturn(__LINE__,'新增回款维护失败');
                }


            }

            $trans->commit();

        }catch (\Exception $e){
            $trans->rollBack();
            return self::setAndReturn(__LINE__, (string) $e);
        }

        return true;
    }

    public function paymentAverageHandle($arr)
    {

        $sumPayment = ContractPaymentRepository::getPaymentSumByContractId($arr['contract_id']);

        //TODO 回填业绩分摊金等于结算业绩分摊金 记得要注释这 //维护回款分摊金额
        $entity = new MyscrmContractDistributionAmountEntity();

        //TODO 没有的话就要键表示首次
        $editAchievement = $entity::find()->where(['contract_id'=>$arr['contract_id']])->all();

        //坏味道修复

        $SummaryAchievement = 0;
        foreach ($editAchievement as $item){
            $SummaryAchievement+=(int)$item['settlement_average_amount'];
        }

        $SummaryAchievement = empty($SummaryAchievement)?1:$SummaryAchievement;//除数不可为0

        $results = [];

        if(empty($editAchievement)){//业绩分摊初始化空就不处理
            return true;
        }

        foreach ($editAchievement as $item){
            $item->receivable_average_amount = round($sumPayment)*$item->settlement_average_amount/$SummaryAchievement;

            //坏味道修复

            $results[] =$item->save();
        }

        $result = false;

        foreach ($results as $val){
            $result = $val;
            if($val === false){//有一次出现失败就表示失败了
                $result = false;
                break;
            }

        }

        return $result;

    }


    public function achievementHandle($arr,$type = 'add')
    {
        //TODO 增加到业绩产品表
        $appPrice = ApplicationPriceRepository::getApplicationPriceByApplicationId($arr['application_id']);//产品单价

        $contractAndApp = ContractApplicationRepository::getContractApplicationAppId($arr['contract_application_id']);//订单产品信息
        $appRes = MyscrmContractApplicationService::getApplicationInfoByApplicationId($arr['application_id']);//产品基本信息
        $getContractApplication = ContractApplicationRepository::getContractApplicationByContractId($arr['contract_id']);//合同下基本信息产品
        $contractModel = ContractManageRepository::getContractManageModelByContractId($arr['contract_id']);

        $sign_amount = $contractModel->sign_amount;//签约金
        $rent_amount = $contractModel->rent_amount;//租金

        $authorization_numeric = $contractAndApp->authorization_numeric;//产品基本信息授权数
        $matchingRule = $appRes['matching_rule'];//产品匹配规则
        $delivery_rules = $appRes['delivery_rules'];//业绩完成规则
        //TODO 需要该条的标准总额
        $StandardAmount = $contractAndApp->amount;

        //TODO 需要标准总额合计
        $StandardAmountAll = 0;
        foreach ($getContractApplication as $app){
            $StandardAmountAll += $app['amount'];//标准总额合计
        }

        $authorization_numeric = empty($authorization_numeric)?1:$authorization_numeric;

        //Division by zero
        if($StandardAmountAll == 0){
            $StandardAmountAll = 1;
        }

        $formula = (int)$arr['total_num']/(int)$authorization_numeric*(int)$StandardAmount/(int)$StandardAmountAll;

        if($delivery_rules == 1 && $matchingRule ==2&&!empty((int)$StandardAmountAll)){//TODO $formula2A 按产品名称
            $formula = (int)$StandardAmount/(int)$StandardAmountAll;//该产品的标准总额 / 总标准总额 * 基本信息的产品租金金额
        }

        $arr['amount'] =$contractAndApp->amount;
        $arr['settlement_type'] =$contractAndApp->settlement_type;
        $arr['settlement_scale'] =$contractAndApp->settlement_scale;
        $arr['discount'] =$contractAndApp->discount;
        $arr['contract_type'] = empty($arr['unique_name'])?$contractAndApp->contract_type:$arr['contract_type'];//通过是否 unique_name 判断来源租户还是
        $arr['unit'] =$contractAndApp->unit;
        $arr['price'] = $appPrice['price'];
        $arr['application_name'] = $appRes['application_name'];//产品名称

        $arr['sign_average_amount'] =  round($formula*$sign_amount);//签约分摊金
        $arr['product_average_amount'] = round($formula*$rent_amount);//产品租金分摊金

        $arr['__type'] = $type;//表示增加

        $res = AuthorizationAchievementRepository::addAuthorizationAchievement($arr);

        $achievementSettlementAmount = $this->achievementSettlementAmount($arr['contract_id']); //已结算金额合计

        if(empty($achievementSettlementAmount)){
            return false;
        }

        unset($arr['auth_info']);
        $this->putLog('addAuthorizationAchievement_arr=>'.json_encode($arr,true),__METHOD__,$res);

        $this->putLog('addAuthorizationAchievement=>'.$res,__METHOD__,$res);
        $this->putLog('$formula=>'.$formula,__METHOD__,$res);
        $this->putLog('$achievementSettlementAmount=>'.$achievementSettlementAmount,__METHOD__,$achievementSettlementAmount);

        return $res;
    }



    /**
     * @sine 2017-8-18
     * @auth zhoud01@mingyuanyun.com
     * 获取签约产品
     */
    public function getContractApplication($contractId)
    {
        return ContractApplicationRepository::getContractApplicationByContractId($contractId);
    }

    /**
     * @sine 2017-8-18
     * @auth zhoud01@mingyuanyun.com
     * 更新业绩 已结算金额合计
     */
    public function achievementSettlementAmount($contractId)
    {
        $AuthorizationAchievement = AuthorizationAchievementRepository::getAuthorizationAchievementByContractId($contractId);

        //结算金额汇总
        $settlement_average_amount = 0;
        foreach ($AuthorizationAchievement as $item){
            $settlement_average_amount += $item['settlement_average_amount'];
        }

        $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); // 获取model
        $contractModel->balance_amount = $settlement_average_amount; //结算金额

        //坏味道修复
        return $contractModel->save();

    }


    /**
     * @sine 2017-8-14
     * @auth zhoud01@mingyuanyun.com
     * 业绩分摊处理
     */
    public function achievementGrouping($contractId)
    {
        //分组并且增加到业绩
        $distributionArr = $this->getAuthorizationAchievementByContractId($contractId);//业绩产品信息数据源

        //TODO 将业绩先分组后插入业绩分摊表 分组原则按照 开通时间 是否SAAS 合同属性 其中云客签约-直属/联营 开通时间 = 合同录入时间
        //TODO 依据合同性质以不同处理因此需要在源头截断因为原逻辑会在增加产品时自动给分摊业绩表增加记录
        //TODO 开始分组

        $contractInfo = $this->getContractInfo($contractId);
        $contractInfo = $contractInfo['contract'];
        $company_id = $contractInfo['company_id'];
        $area_id = $contractInfo['area_id'];
        $sign_people_id = $contractInfo['sign_people_id'];
        $sign_people_department_by = $contractInfo['sign_people_department_by'];
        $input_date = $contractInfo['input_date'];

        $isnotSaas = 'a3c8f32d-374b-4772-95e9-0f3a84f2f1a1';//非SAAS业绩归属小玲

        $result = [];
        foreach($distributionArr as $k=>$v){
            if(!isset($result[$v['establish_time'].'--'.$v['contract_type'].'--'.$v['is_saas']])){
                $result[$v['establish_time'].'--'.$v['contract_type'].'--'.$v['is_saas']]=$v;

                $result[$v['establish_time'].'--'.$v['contract_type'].'--'.$v['is_saas']]['user_id'] = $v['is_saas'] == 1?$sign_people_id:$isnotSaas;
                $result[$v['establish_time'].'--'.$v['contract_type'].'--'.$v['is_saas']]['area_id'] = $area_id;
                $result[$v['establish_time'].'--'.$v['contract_type'].'--'.$v['is_saas']]['department_id'] = $sign_people_department_by;
            }else{
                $result[$v['establish_time'].'--'.$v['contract_type'].'--'.$v['is_saas']]['product_average_amount']+=$v['product_average_amount'];
                $result[$v['establish_time'].'--'.$v['contract_type'].'--'.$v['is_saas']]['sign_average_amount']+=$v['sign_average_amount'];
                $result[$v['establish_time'].'--'.$v['contract_type'].'--'.$v['is_saas']]['settlement_average_amount']+=$v['settlement_average_amount'];

            }
        }

        //erp-interface/get-users
        return $this->saveDistributionAmountByAuthorize($contractId,$input_date, $result);
    }



    /**
     * @sine 2017-7-25
     * @auth zhoud01@mingyuanyun.com
     * 获取开通信息汇总
     */
    public function GetContractOrderSummary($contractNum)
    {
        //坏味道修复
        return OrganizationToAuthorizeRepository::getContractOrderSummary($contractNum);

    }

    /**
     * @sine 2017-7-25
     * @auth zhoud01@mingyuanyun.com
     * 获取产品信息
     */
    public function GetApplicationInfoByApplicationId($application_id)
    {
        //坏味道修复
        return MyscrmContractApplicationService::getApplicationInfoByApplicationId($application_id);
    }

    /**
     * @sine 2017-6-15
     * @auth zhoud01@mingyuanyun.com
     * 获取广告消耗信息
     */

    public function getAdOrganizationInfo($contractId)
    {
        // TODO 合同不存在返回错误 管理库里点

        $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); // 获取model
        if (empty($contractModel)) { // 合同不存在
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_EXISTS);
        }

        // TODO 返回广告信息
        $data = ContractNumToAdDrainRepository::getAdDrainListByContractId($contractId);

        return $data;
    }


    /**
     * @sine 2017-6-15
     * @auth zhoud01@mingyuanyun.com
     * 增加广告记录
     */
    public function AddAdList($lists,$contractId){

        // TODO 合同不存在返回错误

        $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); // 获取model
        if (empty($contractModel)) { // 合同不存在
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_EXISTS);
        }

        $data = ContractNumToAdDrainRepository::addAdDrainListByContractId($lists,$contractId);

        return $data;

    }

    /**
     * @sine 2017-6-15
     * @auth zhoud01@mingyuanyun.com
     * 修改广告记录
     */
    public function EditAdList($contractId,$arr,$idToDelpath=null){

        // TODO 合同不存在返回错误

        $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); // 获取model
        if (empty($contractModel)) { // 合同不存在
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_EXISTS);
        }

        // TODO 修改广告信息
        $data = ContractNumToAdDrainRepository::editAdDrainListByContractId($contractId,$arr,$idToDelpath);
        return $data;

    }


    /**
     * @sine 2017-6-16
     * @auth zhoud01@mingyuanyun.com
     * 删除广告记录
     */
    public function DelAdList($id,$contractId){
        // TODO 合同不存在返回错误

        $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); // 获取model
        if (empty($contractModel)) { // 合同不存在
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_EXISTS);
        }

        $data = ContractNumToAdDrainRepository::delAdDrainListByContractId($id,$contractId);

        return $data;

    }



    /**
     * 获取合同性质
     * @return array
     */
    public function getContractNatures()
    {
        return ContractPropertyRepository::getAllContractProperty();
    }

    /**
     * 根据性质id,获取合同来源
     * @param string $propertyId 性质id
     * @return obj
     */
    public function getContractSource($propertyId)
    {
        return ContractPropertyRepository::getContractSourceByPropertyId($propertyId);
    }

    /**
     * 根据性质id,获取帐套公司列表
     * @param string $propertyId 性质id
     * @return array
     */
    public function getContractAccountCompanyList($propertyId)
    {
        return ContractAccountCompanyRepository::getContractAccountCompanyListByPropertyId($propertyId);
    }

    /**
     * 根据性质id,获取签署公司列表
     * @param string $propertyId 性质id
     * @return array
     */
    public function getContractCompanyList($propertyId)
    {
        return ContractCompanyRepository::getContractCompanyListByPropertyId($propertyId);
    }

    /**
     * 获取服务机构列表
     * @param string $propertyId 性质id
     * @return array
     */
    public function getAgencyCompanyList($propertyId = '7f856e81-fce8-11e4-bed8-00155d02c832')
    {
        $companyList = ContractCompanyRepository::getContractCompanyListByPropertyId($propertyId);
        $contractCompanyEntity = new ContractCompanyEntity();
        $contractCompanyEntity->company_id = "00000000-0000-0000-0000-000000000000";
        $contractCompanyEntity->property_id = "00000000-0000-0000-0000-000000000000";
        $contractCompanyEntity->company_name = "深圳市明源软件股份有限公司";
        $contractCompanyEntity->created_on = date("Y-m-d H:i:s");
        $companyList[] = $contractCompanyEntity;
        return $companyList;
    }

    /**
     * 获取合同类别
     * @return array
     */
    public function getContractCategories()
    {
        return ContractCategoryRepository::getAllContractCategory();
    }

    /**
     * 获取合同大类
     * @return array
     */
    public function getContractBigClass()
    {
        return ContractBigCategoryRepository::getAllContractBigClass();
    }

    /**
     * 根据大类id,获取合同小类
     * @param string $bigClassId 合同大类
     * @return array
     */
    public function getContractSmallClass($bigClassId)
    {
        return ContractLittlerCategoryRepository::getAllContractLittlerCategoryByBigClassId($bigClassId);
    }

    /**
     * 根据关键字，获取产品名称列表
     * @param string $keyword 关键字
     * @param int $limit 返回条数 传空：则全部返回
     * @param int @other 是否其他产品
     * @return array
     */
    public function getProducts($keyword, $limit, $other = 0)
    {
        $dataList = ApplicationInfoRepository::getApplicationInfoByKeyword($keyword, $limit, $other);
        if (empty($dataList)) {
            $data = [];
        } else {
            foreach ($dataList as $key => $value) {
                $data[$key] = $value->attributes;
                $data[$key]['applicationPrices'] = ApplicationPriceRepository::getAllApplicationPriceByApplicationId($value->application_id); //获取产品价格列表
            }
        }

        return $data;
    }

    /**
     * 根据关键字，获取应收款名称列表
     * @param string $keyword 关键字
     * @return array
     */
    public function getReceivableFundName($keyword)
    {
        return ReceivableItemRepository::getReceivableItemByKeyword($keyword);
    }

    /**
     * 获取款项小类
     * @param string $propertyId 性质id
     * @return array
     */
    public function getFundSmallClass($propertyId)
    {
        return MoneyCategoryItemRepository::getAllMoneyCategoryItemListByPropertyId($propertyId);
    }

    /**
     * 获取所有核算类型
     */
    public function getBussAccountTypes()
    {
        return BussAccountTypesRepository::getAllBussAccountTypes();
    }

    /**
     * 特批授权界面获取合同select2控件下拉选项
     * @param string $keyword 搜索关键字
     * @param string $orgId 租户Id
     * @param string $limit 只显示几条记录
     */
    public static function getContractListForSepcialAuthorizeSelect2($keyword, $orgId, $limit)
    {
        return ContractManageRepository::getContractListForSepcialAuthorizeSelect2($keyword, $orgId, $limit);
    }

    /**
     * 违规合同界面获取合同select2控件下拉选项
     * @param string $keyword 搜索关键字
     * @param string $limit 只显示几条记录
     */
    public static function getContractListForViolatedContractSelect2($keyword, $limit)
    {
        return ContractManageRepository::getContractListForViolatedContractSelect2($keyword, $limit);
    }

    /**
     * 获取合同文档信息
     * @param string $contractId 合同id
     * @return array
     */
    public function getContractDocuments($contractId)
    {
        $excludePDF = false;
        $isAreaRole = RoleService::isAreaRole(Yii::$app->user->identity->userguid);
        if ($isAreaRole) {
            $excludePDF = true;
        }
        $data['file'] = DocumentRepository::getDocumentListByBusinessId($contractId, $excludePDF); //上传文件列表
        $data['contractDocuments'] = ContractDocumentRepository::getContractDocumentListByContractId($contractId); //文档信息列表
        return $data;
    }

    /**
     * 保存合同文档信息
     * @param string $contractId 合同id
     * @param array $files 文件数组
     * @param array $documents 文档信息数组
     * @return boolean
     */
    public function saveContractDocuments($contractId, $files, $documents)
    {
        $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); // 获取model
        if (empty($contractModel)) { // 合同不存在
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_EXISTS);
        }

        //处理保存文件
        if (!empty($files) && is_array($files)) {

            foreach ($files as $value) {
                if (!isset($value ['__type'])) {
                    continue;
                }
                switch ($value ['__type']) {
                    case 'delete' :
                        DocumentRepository::delDocumentById($value ['document_id']);
                        break;
                    case 'add' :
                        $documentModel = new DocumentModel ();
                        $documentModel->setAttributes($value);
                        $explode = explode('.', $value['document_name']);
                        $extName = end($explode);
                        $documentModel->document_ext_name = $extName;
                        $documentModel->business_id = $contractId;
                        $documentModel->modified_on = date("Y-m-d H:i:s");
                        if ($documentModel->validate()) {
                            DocumentRepository::addDocument($documentModel);
                        }
                        break;
                    case 'update' :
                        $documentModel = new DocumentModel ();
                        $documentModel->load($value, '');
                        $explode = explode('.', $value['document_name']);
                        $extName = end($explode);
                        $documentModel->document_ext_name = $extName;
                        $documentModel->business_id = $contractId;
                        $documentModel->modified_on = date("Y-m-d H:i:s");
                        if ($documentModel->validate()) {
                            DocumentRepository::updateDocument($documentModel);
                        }
                        break;
                }
            }
        }


        // 处理保存文档信息
        if (!empty($documents) && is_array($documents)) {
            foreach ($documents as $value) {
                if (!isset($value ['__type'])) {
                    $value ['__type'] = 'update';
                }
                switch ($value ['__type']) {
                    case 'delete' :
                        ContractDocumentRepository::deleteContractDocumentByContractIdAndDocumentId($contractId, $value ['document_id']);
                        break;
                    case 'add' :
                        $contractDocument = new ContractDocumentModel ();
                        $contractDocument->setScenario('add');
                        $contractDocument->load($value, '');
                        if ($contractDocument->validate()) {
                            $contractDocument->contract_id = $contractId;
                            ContractDocumentRepository::addContractDocument($contractDocument); // 新增合同文档信息
                        }
                        break;
                    case '' :
                    case 'update' :
                        $contractDocument = new ContractDocumentModel ();
                        $contractDocument->setScenario('update');
                        $contractDocument->load($value, '');
                        if ($contractDocument->validate()) {
                            ContractDocumentRepository::updateContractDocument($contractDocument); // 新增合同文档信息
                        }
                        break;
                }
            }
        }

        return true;
    }

    /**
     * 获取合同基本信息
     */
    public function getContractManageInfo($contractId)
    {
        return ContractManageRepository::getContractManageModelByContractId($contractId); // 获取model
    }

    /**
     * 获取业绩信息
     * @param string $contractId 合同id
     * @return array 返回业绩信息数组数据
     */
    public function getSignAchievement($contractId)
    {

        $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); // 获取model
        if (empty($contractModel)) { // 合同不存在
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_EXISTS);
        }

        $r_data['contract_id'] = $contractModel->contract_id; //合同id
        $r_data['contract_deal_discount'] = $contractModel->contract_deal_discount; //合同成交折扣
        $r_data['draw_project_numeric'] = $contractModel->draw_project_numeric; //提成项目数
        $r_data['project_numeric'] = $contractModel->project_numeric; //提成项目数
        $r_data['contract_property_name'] = ContractPropertyRepository::getPropertyNameByPropertyId($contractModel->contract_property_id); //获取性质名称

        $r_data['signAchievements'] = SignAchievementRepository::getSignAchievementListByContractId($contractId); //根据合同id,获取签约业绩

        foreach ($r_data['signAchievements'] as $key => $val) {
            $r_data['signAchievements'][$key]['belong_name'] = $this->getUserNameById($val['belong_by']); //获取归属人名称
            $r_data['signAchievements'][$key]['manager_name'] = $this->getUserNameById($val['manager_by']); //获取ERP客户经理名称
            $r_data['signAchievements'][$key]['area_name'] = $this->getBuNameById($val['area_by']); //获取区域名称
            $r_data['signAchievements'][$key]['department_name'] = $this->getBuNameById($val['department_by']); //获取部门名称

            $r_data['signAchievements'][$key]['erp_achievement_belong_name'] = $this->getUserNameById($val['erp_achievement_belong']); //获取ERP归属人名称
            $r_data['signAchievements'][$key]['erp_achievement_belong_abu_name'] = $this->getBuNameById($val['erp_achievement_belong_abu']); //获取ERP业绩归属ABU
            $r_data['signAchievements'][$key]['erp_achievement_belong_abu_owner_name'] = $this->getUserNameById($val['erp_achievement_belong_abu_owner']); //获取ERP归属ABU负责人
            $r_data['signAchievements'][$key]['erp_achievement_belong_bu_manager_name'] = $this->getUserNameById($val['erp_achievement_belong_bu_manager']); //获取ERP归属部门经理
            $r_data['signAchievements'][$key]['erp_achievement_belong_bu_name'] = $this->getBuNameById($val['erp_achievement_belong_bu']); //获取ERP业绩归属部门
        }

        $r_data['paymentAchievement'] = PaymentAchievementRepository::getPaymentAchievementListByContractId($contractId); //根据合同id,获取回款业绩
        foreach ($r_data['paymentAchievement'] as $key => $val) {
            $r_data['paymentAchievement'][$key]['receivable_item_name'] = ReceivableItemRepository::getReceivableItemNameByItemId($val['receivable_item_id']); //获取款项名称
            $r_data['paymentAchievement'][$key]['money_category_item_name'] = MoneyCategoryItemRepository::getMoneyCategoryItemNameByItemId($val['money_category_item_id']); //获取款项小类名称

            $r_data['paymentAchievement'][$key]['belong_name'] = $this->getUserNameById($val['belong_by']); //获取归属人名称
            $r_data['paymentAchievement'][$key]['manager_name'] = $this->getUserNameById($val['manager_by']); //获取ERP客户经理名称
            $r_data['paymentAchievement'][$key]['area_name'] = $this->getBuNameById($val['area_by']); //获取区域名称
            $r_data['paymentAchievement'][$key]['department_name'] = $this->getBuNameById($val['department_by']); //获取部门名称

            $r_data['paymentAchievement'][$key]['erp_achievement_belong_name'] = $this->getUserNameById($val['erp_achievement_belong']); //ErpUserRepository::getUserNameByBuguid($val['erp_achievement_belong']); //获取ERP归属人名称
            $r_data['paymentAchievement'][$key]['erp_achievement_belong_abu_name'] = $this->getBuNameById($val['erp_achievement_belong_abu']); //获取ERP业绩归属ABU
            $r_data['paymentAchievement'][$key]['erp_achievement_belong_abu_owner_name'] = $this->getUserNameById($val['erp_achievement_belong_abu_owner']); //获取ERP归属ABU负责人
            $r_data['paymentAchievement'][$key]['erp_achievement_belong_bu_manager_name'] = $this->getUserNameById($val['erp_achievement_belong_bu_manager']); //获取ERP归属部门经理
            $r_data['paymentAchievement'][$key]['erp_achievement_belong_bu_name'] = $this->getBuNameById($val['erp_achievement_belong_bu']); //获取ERP业绩归属部门
        }

        return $r_data;
    }

    /**
     * 保存业绩修改
     * @param string $contractId 合同id
     * @param int $drawProjectNumeric 提交项目数
     * @param array $signAchievements 签约业绩列表数组
     * @param array $paymentAchievements 回款业绩列表
     * @param string $achievementRemark 业绩备注
     * @return array
     */
    public function saveSignAchievement($contractId, $drawProjectNumeric, $signAchievements, $paymentAchievements, $projectNumeric = 0, $achievementRemark)
    {
        $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); // 获取model
        if (empty($contractModel)) { // 合同不存在
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_EXISTS);
        }
        $contractModel->draw_project_numeric = $drawProjectNumeric;
        $contractModel->project_numeric = $projectNumeric;
        $contractModel->achievement_remark = $achievementRemark;
        $contractModel->save();


        if (!empty($signAchievements)) {
            foreach ($signAchievements as $value) {
                // 处理签约业绩信息
                if (!isset($value ['__type'])) {
                    $value ['__type'] = 'update';
                }
                switch ($value ['__type']) {
                    case 'delete' :
                        SignAchievementRepository::deleteSignAchievementByAchievementId($value['achievement_id']); //删除签约业绩
                        break;
                    case 'add' :
                        $signAchievementModel = new SignAchievementModel();
                        $signAchievementModel->setScenario('add');
                        $signAchievementModel->load($value, '');
                        $signAchievementModel->contract_id = $contractId;
                        $signAchievementModel->attribute_name = $contractModel->attribute_name;
                        if ($signAchievementModel->validate()) {
                            SignAchievementRepository::addSignAchievement($signAchievementModel); // 新增签约业绩
                        }
                        break;
                    case '' :
                    case 'update' :
                        $signAchievementModel = new SignAchievementModel ();
                        $signAchievementModel->setScenario('update');
                        $signAchievementModel->load($value, '');
                        $signAchievementModel->contract_id = $contractId;
                        if ($signAchievementModel->validate()) {
                            SignAchievementRepository::updateSignAchievement($signAchievementModel); // 更新签约业绩
                        }
                        break;
                }
            }
        }

        // 处理回款业绩信息
        if (!empty($paymentAchievements)) {
            foreach ($paymentAchievements as $value) {
                if (!isset($value ['__type'])) {
                    $value ['__type'] = 'update';
                }
                switch ($value ['__type']) {
                    case 'delete' :
                        PaymentAchievementRepository::deletePaymentAchievementByAchievementId($value['achievement_id']); //删除回款业绩
                        break;
                    case 'add' :
                        $paymentAchievementModel = new PaymentAchievementModel ();
                        $paymentAchievementModel->setScenario('add');
                        $paymentAchievementModel->load($value, '');
                        $paymentAchievementModel->contract_id = $contractId;
                        $paymentAchievementModel->attribute_name = $contractModel->attribute_name;
                        if ($paymentAchievementModel->validate()) {
                            PaymentAchievementRepository::addPaymentAchievement($paymentAchievementModel); // 新增回款业绩
                        }
                        break;
                    case '' :
                    case 'update' :
                        $paymentAchievementModel = new PaymentAchievementModel ();
                        $paymentAchievementModel->setScenario('update');
                        $paymentAchievementModel->load($value, '');
                        $paymentAchievementModel->contract_id = $contractId;
                        if ($paymentAchievementModel->validate()) {
                            PaymentAchievementRepository::updatePaymentAchievement($paymentAchievementModel); // 更新回款业绩
                        }
                        break;
                }
            }
        }

        return true;
    }

    /**
     * 获取最新合同编号
     * @param string $areaCode 区域代码
     * @param string $customerId 客户id
     * @param string $contractCode 合同编号
     * @return string
     */
    public function getContractFlowCode($areaCode, $customerId, $contractCode)
    {
        $maxContractFlowCode = ContractFlowCodeRepository::getMaxContractFlowCode() + 1;

        return ContractFlowCodeRepository::createContractCode($areaCode, $customerId, $maxContractFlowCode, $contractCode);
    }

    /**
     * 导出合同
     * @param null $status
     * @param boolean $property 合同性质
     * @param string $keyword 关键字
     * @param integer $areaId 区域id
     * @param null $signPeopleId
     * @param int $timeType
     * @param string $timeStart
     * @param string $timeEnd
     * @param array $reportType
     * @return array
     * @internal param string $beginDate 结算开始时间
     * @internal param string $endDate 结算结束时间
     */
    public function exportContract($status = null, $property = null, $keyword = null, $areaId = null, $signPeopleId = null, $timeType = 0, $timeStart = '', $timeEnd = '', $reportType = [])
    {
        $objPHPExcel = new \PHPExcel();

        #区域过滤（不是“我的合同”）
        if (empty($areaId) && empty($signPeopleId)) {
            $areaId = self::filterBusinessUnit(\Yii::$app->user->identity);
        }

        #截止时间加一天
        if (!empty($timeEnd)) {
            $timeEnd = date("Y-m-d", strtotime("+1 day", strtotime($timeEnd)));
        }
       
        // 1、合同签约明细表
        if (!empty($reportType) && in_array(self::REPORT_TYPE_SIGN, $reportType)) {
            return $this->exportContractExcel($status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);
        }else{
            $this->makeExcel($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd, $reportType);
        }

        $objWriter = new \PHPExcel_Writer_Excel5($objPHPExcel);
        $fileName = sprintf("hetong-data_%s.xls", \Yii::$app->user->identity->userguid);
        $path = \Yii::getAlias("@mybackend/web/xls/");
        // 文件名称
        if (!is_dir($path)) {
            $mkResult = mkdir($path, 0755);
            $this->_errorLog->log(date('Y-m-d H:i:s') . ";time=" . time() . ";mkResult=" . $mkResult . ";LINE=" . __LINE__);
        }

        $filepath = $path . $fileName;
        $objWriter->save($filepath); //脚本方式运行，保存在当前目录
        $key = $fileName;
        OSS::upload($key, $filepath);
        $ossUrl = OSS::getUrl($key);
        $this->_errorLog->log(date('Y-m-d H:i:s') . ";time=" . time() . ";uploadResult=" . $ossUrl . ";LINE=" . __LINE__);
        return $ossUrl;
    }


    private function makeExcel($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd, $reportType)
    {
        $file_desc = [];
        // 2、合同回款明细表
        if (empty($reportType) || in_array(self::REPORT_TYPE_PAYMENT, $reportType)) {
            $this->exportContractPaymentExecl($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);
            $file_desc[] = '合同回款明细表';
        }
        // 3、签约产品明细表
        if (empty($reportType) || in_array(self::REPORT_TYPE_PRODUCT, $reportType)) {
            $this->exportContractProductExcel($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);
            $file_desc[] = '签约产品明细表';
        }
        // 4、收入明细表
        if (empty($reportType) || in_array(self::REPORT_TYPE_INCOME, $reportType)) {
            //$this->exportContractRevenueExecl($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId);
            $this->exportContractRevenueExecl($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);
            $file_desc[] = '收入明细表';
        }
        // 14、已开票未回款明细表
        if (empty($reportType) || in_array(self::REPORT_TYPE_NO_PAYMENT, $reportType)) {
            //$this->exportContractNoPaymentExecl($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId);
            $this->exportContractNoPaymentExecl($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);
            $file_desc[] = '已开票未回款明细表';
        }
        // 5、签约业绩明细表
//        if (empty($reportType) || in_array(self::REPORT_TYPE_SIGN_ACHIEVE, $reportType)) {
//            $this->exportContractSignAchievementExecl($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);
//            $file_desc[] = '签约业绩明细表';
//        }
        // 6、回款业绩列表
//        if (empty($reportType) || in_array(self::REPORT_TYPE_PAYMENT_ACHIEVE, $reportType)) {
//            $this->exportContractPaymentAchievementExecl($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);
//            $file_desc[] = '回款业绩列表';
//        }
        // 7、交付业绩明细表
//        if (empty($reportType) || in_array(self::REPORT_TYPE_PAY_ACHIEVE, $reportType)) {
//            //$this->exportContractDelyExecl($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId);
//            $this->exportContractDelyExecl($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId , $timeType, $timeStart, $timeEnd);
//            $file_desc[] = '交付业绩明细表';
//        }
        // 8、应收款项明细表
        if (empty($reportType) || in_array(self::REPORT_TYPE_RECEIVABLE, $reportType)) {
            //$this->exportContractReceivableExecl($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId);
            $this->exportContractReceivableExecl($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);
            $file_desc[] = '应收款项明细表';
        }
        // 9、纸质合同统计表
        if (empty($reportType) || in_array(self::REPORT_TYPE_PAPER, $reportType)) {
            //$this->exportContractDocumentExecl($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId);
            $this->exportContractDocumentExecl($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);
            $file_desc[] = '纸质合同统计表';
        }
        // 10、联营区域未上传标的物明细表

//        if (empty($reportType) || in_array(self::REPORT_TYPE_NO_UPLOAD, $reportType)) {
//            $this->exportContractNoUploadTypeExecl($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId);
//            $file_desc = '联营区域未上传标的物明细表';
//        }
        // 11、违规合同列表
//        if (empty($reportType) || in_array(self::REPORT_TYPE_OUT_CONTRACT, $reportType)) {
//            $this->exportContractViolatedExecl($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId);
//            $file_desc = '违规合同列表';
//        }


        /*// 10、联营区域未上传标的物明细表
        if (empty($reportType) || in_array(self::REPORT_TYPE_NO_UPLOAD, $reportType)) {
//            $this->exportContractNoUploadTypeExecl($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId);
            $this->exportContractNoUploadTypeExecl($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);
            $file_desc[] = '联营区域未上传标的物明细表';
        }*/

        // 10、联营区域未上传标的物明细表
        if (empty($reportType) || in_array(self::REPORT_TYPE_NO_UPLOAD, $reportType)) {
//            $this->exportContractNoUploadTypeExecl($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId);
            $this->exportContractNoUploadTypeExecl($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);
            //$file_desc[] = '联营区域未上传标的物明细表';
            $file_desc[] = '代理合同未上传标的物明细表';
        }

        // 11、违规合同列表
        if (empty($reportType) || in_array(self::REPORT_TYPE_OUT_CONTRACT, $reportType)) {
            $this->exportContractViolatedExecl($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);
            $file_desc[] = '违规合同列表';
        }

        // 12、特批发票列表
        if (empty($reportType) || in_array(self::REPORT_TYPE_SPECIAL_INVOICE, $reportType)) {
            //$this->exportContractSpecialInvoiceExecl($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId);
            $this->exportContractSpecialInvoiceExecl($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);
            $file_desc[] = '特批发票列表';
        }

        // 13、特批授权列表
        if (empty($reportType) || in_array(self::REPORT_TYPE_SPECIAL_AUTHORIZE, $reportType)) {
            //$this->exportContractSpecialAuthorizeExecl($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId);
            $this->exportContractSpecialAuthorizeExecl($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);
            $file_desc[] = '特批授权列表';
        }

        //15、坏账明细表
        if (empty($reportType) || in_array(self::REPORT_TYPE_BAD_DEBT_DETAIL, $reportType)){
            //$this->exportContractBadDebtDeail($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId);
            $this->exportContractBadDebtDeail($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);
            $file_desc[] = '坏账明细表';
        }

        //16、收入结转表
        if (empty($reportType) || in_array(self::REPORT_REVENUE_RECOGNITION, $reportType)){

            $this->exportRevenueRecognition($objPHPExcel,$timeType, $timeStart, $timeEnd);
            $file_desc[] = '收入结转表';

        }

        //17、收入&回款&应收对应表

        if (empty($reportType) || in_array(self::REPORT_PAYMENT_RECEIVABLE, $reportType)){

            $this->exportRevenueReceivablePayment($objPHPExcel,$timeType, $timeStart, $timeEnd);
            $file_desc[] = '收入回款应收对应表';

        }

        $this->_errorLog->log(date('Y-m-d H:i:s') . ";time=" . time() . ";LINE=" . __LINE__. ";Report=" . implode(',', $file_desc));
    }

    private function getRecognitionRange($timeStart, $timeEnd){

        $recognitionListDate = RevenueRecognitionRepository::getRecognitionListDateByTime($timeStart,$timeEnd);
        $recognitionBeginList = [];
        $recognitionEndList = [];
        foreach ($recognitionListDate as $item){
            $recognitionBeginList[] = $item ['recognition_begin'];
            $recognitionEndList[] = $item ['recognition_end'];
        }

        return ['recognitionBegin'=>empty($recognitionBeginList)?'':min($recognitionBeginList),'recognitionEnd'=>empty($recognitionBeginList)?'':max($recognitionEndList)];
    }
    public function exportRevenueRecognition($objPHPExcel,$timeType, $timeStart, $timeEnd)
    {
        $recognitionRange = self::getRecognitionRange($timeStart, $timeEnd);

        $revenueRecognitionModel = new RevenueRecognitionModel(['scenario' => 'selectRevenueRecognition']);
        $revenueRecognitionModel->recognition_begin = $recognitionRange['recognitionBegin'];
        $revenueRecognitionModel->recognition_end = $recognitionRange['recognitionEnd'];

        $recognitionList = RevenueRecognitionRepository::getRecognitionRevenueContractByDate($revenueRecognitionModel);
        //设置当前的sheet
        $activeSheet = self::getActiveSheet($objPHPExcel);
        $activeSheet->getStyle('A:z')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
        $activeSheet->setTitle('收入结转表');

        //设置列标题
        $columnTitles = [
            '帐套公司', '合同所属公司', '收入项编码', '合同编号', '签约客户全称', '签约日期',
            '合同录入日期', '收入确认开始期间', '签约金额', '合同性质', '合同大类', '合同小类', '收入类别',
            '收入项名称','收入项金额','收入确认方式','租期(运维期)起始日期','租期(运维期)截止日期',
            '结转期间(起始)','结转期间(终止)','上期累计确认收入','本期确认收入','本期累计确认收入','不含税收入','本期剩余'
            ,'未确认收入已发生坏账','已确认收入发生坏账','金蝶核销坏账','结转时间','收入来源'
        ];

        $columnIndex = 'A';
        foreach ($columnTitles as $key => $value) {
            $activeSheet->setCellValue($columnIndex . '1', $value);
            $activeSheet->getColumnDimension($columnIndex)->setWidth(15);
            $activeSheet->getStyle($columnIndex . '1')->getFont()->setBold(true);
            $columnIndex++;
        }

        if (!empty($recognitionList)){
            $j = '2';
            foreach ($recognitionList as $row => $recognition) {
                $i = 'A';
                $activeSheet->setCellValue($i . $j, $recognition["account_company_name"]);//帐套公司
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["company_name"]);//合同所属公司
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["income_code"]);//收入项编码
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["contract_code"]);//合同编号
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["customer_full_name"]);//签约客户全称
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["sign_date"]);//签约日期
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["input_date"]);//合同录入日期
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["recognition_begin"]);//收入确认开始期间
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["sign_amount"]);//签约金额
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["property_name"]);//合同性质
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["big_category_name"]);//合同大类
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["littler_category_name"]);//合同小类
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["type_name"]);//收入类别
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["finance_type_name"]);//收入项名称
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["amount"]);//收入项金额
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["recognition_type"]);//收入确认方式
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["begin_on"]);//租期(运维期)起始日期
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["end_on"]);//租期(运维期)截止日期
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["recognition_begin"]);//结转期间(起始)
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["recognition_end"]);//结转期间(终止)
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["last_total_recognition_amount"]);//上期累计确认收入
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["this_recognition_amount"]);//本期确认收入
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["this_total_recognition_amount"]);//本期累计确认收入
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["this_total_recognition_excluding_tax_amount"]);//不含税收入
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["recognition_type"]);//本期剩余
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["unrecognized_bad_debt_amount"]);//未确认收入已发生坏账
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["recognized_bad_debt_amount"]);//已确认收入发生坏账
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["kingdee_bad_debt_amount"]);//金蝶核销坏账
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["recognition_time"]);//结转时间
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["revenue_source"]);//收入来源
                $j++;
            }
        }

    }

    public function exportRevenueReceivablePayment($objPHPExcel,$timeType, $timeStart, $timeEnd)
    {
        $recognitionRange = self::getRecognitionRange($timeStart, $timeEnd);
        $revenueRecognitionModel = new RevenueRecognitionModel(['scenario' => 'selectRevenueRecognition']);
        $revenueRecognitionModel->recognition_begin = $recognitionRange['recognitionBegin'];
        $revenueRecognitionModel->recognition_end = $recognitionRange['recognitionEnd'];

        $recognitionList = RevenueRecognitionRepository::getRevenueReceivablePaymentListByDate($revenueRecognitionModel);
        //设置当前的sheet
        $activeSheet = self::getActiveSheet($objPHPExcel);
        $activeSheet->getStyle('A:z')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
        $activeSheet->setTitle('收入结转表');

        //设置列标题
        $columnTitles = [
            '合同所属公司', '合同编号', '签约客户', '合同签署公司', '签约日期', '录入日期',
            '合同性质', '合同大类', '合同小类', '收入项编码', '收入项类型', '收入项金额',
            '本期收入','累计收入','最后结转期间','应收款金额','本期回款','累计回款','备注',
        ];

        $columnIndex = 'A';
        foreach ($columnTitles as $key => $value) {
            $activeSheet->setCellValue($columnIndex . '1', $value);
            $activeSheet->getColumnDimension($columnIndex)->setWidth(15);
            $activeSheet->getStyle($columnIndex . '1')->getFont()->setBold(true);
            $columnIndex++;
        }

        if (!empty($recognitionList)){
            $j = '2';
            foreach ($recognitionList as $row => $recognition) {
                $i = 'A';
                $activeSheet->setCellValue($i . $j, $recognition["company_name"]);//合同所属公司
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["contract_code"]);//合同编号
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["customer_full_name"]);//签约客户
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["company_name"]);//合同签署公司
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["sign_date"]);//签约日期
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["input_date"]);//录入日期
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["contract_finance_property"]);//合同性质
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["big_category_name"]);//合同大类
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["littler_category_name"]);//合同小类
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["income_code"]);//收入项编码
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["finance_type_name"]);//收入项类型
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["sign_amount"]);//收入项金额
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["this_recognition_amount"]);//本期收入
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["total_recognition_amount"]);//累计收入
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["last_recognition_end"]);//最后结转期间
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["this_payment_amount"]);//应收款金额
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["this_payment_amount"]);//本期回款
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["summary_payment_amount"]);//累计回款
                $i++;
                $activeSheet->setCellValue($i . $j, $recognition["remark"]);//备注
                $j++;
            }
        }

    }

    /**
     * 导出坏账明细表
     * @param object $objPHPExcel phpexcel
     * @param integer $status 合同状态
     * @param string $property 合同性质
     * @param string $keyword
     * @param string $areaId 区域
     * @param string $signPeopleId 签约人
     * @throws \yii\base\InvalidConfigException
     */
    public function exportContractBadDebtDeail($objPHPExcel, $status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd)
    {
        /** @var  $contractRepository ContractManageRepository */
        $contractRepository = Yii::createObject(ContractManageRepository::className());
        $badDebtList = $contractRepository->getBadDebtListForExport($status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);
        //设置当前的sheet
        $activeSheet = self::getActiveSheet($objPHPExcel);
        $activeSheet->getStyle('A:z')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
        $activeSheet->setTitle('坏账明细表');

        //设置列标题
        $columnTitles = ['合同所属区域', '合同编号', '客户简称', '签约客户名称', '合同签署公司', '签约日期',
            '录入日期', '签约金额', '合同性质', '累计回款', '累计开票金额', '坏账金额', '坏账原因'
        ];

        $columnIndex = 'A';
        foreach ($columnTitles as $key => $value) {
            $activeSheet->setCellValue($columnIndex . '1', $value);
            $activeSheet->getColumnDimension($columnIndex)->setWidth(15);
            $activeSheet->getStyle($columnIndex . '1')->getFont()->setBold(true);
            $columnIndex++;
        }

        $areaNameGroupById = $this->batchGetAreaName($badDebtList);

        if (!empty($badDebtList)){
            $j = '2';
            foreach ($badDebtList as $row => $badDebt) {
                $i = 'A';
                $areaName = $this->checkKeyIsset($areaNameGroupById, $badDebt['area_id']);
                $activeSheet->setCellValue($i . $j, $areaName);
                $i++;
                $activeSheet->setCellValue($i . $j, $badDebt['contract_code']);
                $i++;
                $activeSheet->setCellValue($i . $j, $badDebt['customer_name']);
                $i++;
                $activeSheet->setCellValue($i . $j, $badDebt['customer_full_name']);
                $i++;
                $activeSheet->setCellValue($i . $j, $badDebt['contract_company_name']);
                $i++;
                $activeSheet->setCellValue($i . $j, StringHelper::formatDate($badDebt['sign_date'], 'Y-m-d'));
                $i++;
                $activeSheet->setCellValue($i . $j, StringHelper::formatDate($badDebt['input_date'], 'Y-m-d'));
                $i++;
                $activeSheet->setCellValue($i . $j, $badDebt['sign_amount']);
                $i++;
                $activeSheet->setCellValue($i . $j, $badDebt['property_name']);
                $i++;
                $activeSheet->setCellValue($i . $j, $badDebt['received_amount']);
                $i++;
                $activeSheet->setCellValue($i . $j, $badDebt['billing_amount']);
                $i++;
                $activeSheet->setCellValue($i . $j, $badDebt['receivable_amount'] - $badDebt['received_amount']);
                $i++;
                $activeSheet->setCellValue($i . $j, $badDebt['bad_debt_reason']);
                $j++;
            }
        }
    }

    /**
     * 租期即将到期授权提醒
     * @param $expiredDays 过期天数：30、60
     * @return array|\yii\db\ActiveRecord[]
     */
    public function authorizationExpiredRemind($expiredDays)
    {
        $expiredDate = date_add(date_create_from_format('Y-m-d H:i:s', ContractEntity::getDbNowDate()), \DateInterval::createFromDateString($expiredDays . ' Day'));
        $expiredDate = date_format($expiredDate, 'Y-m-d');
        $expiredAuthorizations = ContractManageRepository::getAuthorizationExpiredRemind($expiredDate);
        foreach ($expiredAuthorizations as $key => $item) {
            //获取合同信息
            $contractInfo = ContractManageRepository::getContractManageModelByContractId($item['contract_id']);
            $emailParams = [
                'contractId' => $contractInfo->contract_code,
                'custName' => $contractInfo->customer_name,
                'custFullName' => $contractInfo->customer_full_name,
                'signAmount' => $contractInfo->sign_amount,
                'uniqueName' => $item['UniqueName'],
                'period' => date('Y-m-d', strtotime($item['BeginOn'])) . '至' . date('Y-m-d', strtotime($item['EndOn']))
            ];
            $apps = ContractManageRepository::getContractApps($item['ContractId']);
            if (empty($apps)) {
                $apps = [];
            }
            $strapps = '';
            foreach ($apps as $appkey => $appitem) {
                $strapps .= $appitem['FriendlyName'] . ':' . $appitem['TotalNum'] . ';';
            }

            $emailParams['apps'] = $strapps;
            $this->sendEmailForAuthorizeExpired($item['sign_people_id'], '【合同管理】租期到期提醒', 'authorizeExpired', $emailParams, ['fuxl@mysoft.com.cn' => '付小玲']);
        }
    }

    /**
     * erp获取合同信息
     * @param string $propertyId 合同性质ID
     * @param date|null $startReviewDate 开始审核日期（date|null:date:给定日期以后审核的数据，null：所有审核的合同数据）
     * @param int $page 取数页码,default=1
     * @param int $pageSize 分页大小,default=20
     * @return array|\yii\db\ActiveRecord[]
     */
    public static function getContractsForERP($propertyId, $startReviewDate, $page = 1, $pageSize = 20)
    {
        return ContractManageRepository::getContractsForERP($propertyId, $startReviewDate, $page, $pageSize);
    }

    /**
     * 获取可开通产品名称
     * @authr zhoud01
     * @sine 2017-7-22
     * @param type $contract_id
     */
    public static function getProductDatas($contract_id)
    {
        //坏味道修复
        return ContractApplicationRepository::getStandardContractApplicationByContractId($contract_id);//获取标准签约产品
        //$applicationData = ContractApplicationRepository::getAllContractApplicationByContractId($contract_id);//获取所有签约产品

    }

    /**
     * 获取租户列表中可授权的产品
     * @authr zhoud01
     * @sine 2017-7-22
     * @param type $contract_id
     */
    public static function getTenantAuthorizeProductDatas()
    {
        return MyscrmApplicationEntity::find()->select("*")->asArray()->all();
    }


    /**
     * 获取当前活动表格
     * @param \PHPExcel $objPHPExcel
     * @return \PHPExcel_Worksheet
     */
    private static function getActiveSheet($objPHPExcel)
    {
        if (self::$sheetIndex == 0) {
            $objPHPExcel->setActiveSheetIndex(self::$sheetIndex);
            $activeSheet = $objPHPExcel->getActiveSheet();
        } else {
            $activeSheet = $objPHPExcel->createSheet(self::$sheetIndex);
        }
        self::$sheetIndex++;
        return $activeSheet;
    }

    /**
     * 获取产品名称
     * @param type $contract_id
     */
    private static function getProductNames($contract_id)
    {
        $name = '';
        $applicationData = ContractApplicationRepository::getStandardContractApplicationByContractId($contract_id);
        if (!empty($applicationData)) {
            $productName = ArrayHelper::getColumn($applicationData, 'application_name');
            $name = implode('、', $productName);
        }
        return $name;
    }

    /**
     * 获取属性名称
     * @param type $value
     * @return type
     */
    private static function getAttributeName($value)
    {
        $name = '';
        $attributeName = explode(',', $value);
        if (!empty($attributeName)) {
            $attr = [];
            if (isset($attributeName[0]) && $attributeName[0] == 'true') {
                $attr[] = '新增';
            }
            if (isset($attributeName[1]) && $attributeName[1] == 'true') {
                $attr[] = '混签';
            }
            if (isset($attributeName[2]) && $attributeName[2] == 'true') {
                $attr[] = '续签';
            }
            if (isset($attributeName[3]) && $attributeName[3] == 'true') {
                $attr[] = '增购';
            }
            $name = implode('，', $attr);
        }
        return $name;
    }

    private static function tranContractTypeAttributeName($contractType)
    {
        switch ($contractType){
            case 1:
                $ret = '新增';
                break;
            case 2:
                $ret = '增购';
                break;
            case 3:
                $ret = '续签';
                break;
            default:
                $ret = '新增';
                break;
        }

        return $ret;
    }

    /**
     * 获取租户的合同合同授权
     * @param $org_id
     * @return array
     */
    public function getOrganizationContractDetail($org_id)
    {
        $organizationData = MyscrmOrganizationEntity::find()->filterWhere([
            'Id' => $org_id,
        ])->indexBy('Id')->asArray()->all();

        $contractData = MyscrmContractEntity::find()->filterWhere([
            'OrganizationId' => $org_id,
        ])->indexBy('ContractId')->asArray()->all();

        $authorizeData = MyscrmOrganizationToAuthorizeEntity::find()->filterWhere([
            'OrganizationId' => $org_id,
        ])->asArray()->all();

        $data = [];

        $contractNumAndAuthorizeId = []; // 一个合同可授权多次

        foreach ($contractData as $contract) {
            if (!isset($data[$contract['OrganizationId']])) {
                // 判断是否存在这个租户
                if (!isset($organizationData[$contract['OrganizationId']])) {
                    Yii::info('租户不存在，ID:'. $contract['OrganizationId']);
                    continue;
                }

                $organization = $organizationData[$contract['OrganizationId']];

                $data[$contract['OrganizationId']] = [
                    "RentInfoId"   => $organization['Id'],  //租户ID
                    "RentInfoName" => $organization['FriendlyName'],  //租户名字
                    "CustomerID"   => $organization['CstGuid'], //客户ID
                    "CustomerName" => $organization['TopCstName'], //客户姓名
                    "RentInfoCode" => $organization['UniqueName'], //租户code
                    "RentOpenDate" => $organization['CreatedOn'], //租户开通时间
                    "RentContract" => [],
                ];
            }

            if (!isset($data[$contract['OrganizationId']]['RentContract'][$contract['ContractNum']])) {
                $data[$contract['OrganizationId']]['RentContract'][$contract['ContractNum']] = [
                    "ContractID"      => null,//合同guid
                    "ContractCode"    => $contract['ContractNum'], //合同编号
                    "CustomerID"      => "e5ef91c9-1125-4b33-95dd-876d68a302db", //客户ID
                    "CustomerName"    => "客户姓名", //客户姓名
                    "ContractProduct" => [],
                ];
            }
            $contractNumAndAuthorizeId[$contract['ContractId']] = $contract['ContractNum'];
        }

        $contractNums = array_unique(array_values($contractNumAndAuthorizeId));//合同数据


        $allContracts = $this->getAllContracts($contractNums);

        $applications = $this->getAllOnShelfApplications();


        foreach ($authorizeData as $authorize) {

            if (!isset($data[$authorize['OrganizationId']])) {
                continue;   //不存在此租户
            }

            if (!isset($contractNumAndAuthorizeId[$authorize['ContractId']])) {
                continue;//不存在此授权
            }

            if (isset($allContracts[$contractNumAndAuthorizeId[$authorize['ContractId']]])) {
                $contract = $allContracts[$contractNumAndAuthorizeId[$authorize['ContractId']]];

                $data[$authorize['OrganizationId']]['RentContract'][$contractNumAndAuthorizeId[$authorize['ContractId']]]['ContractID'] = $contract['contract_id'];
                $data[$authorize['OrganizationId']]['RentContract'][$contractNumAndAuthorizeId[$authorize['ContractId']]]['CustomerID'] = $contract['customer_id'];
                $data[$authorize['OrganizationId']]['RentContract'][$contractNumAndAuthorizeId[$authorize['ContractId']]]['CustomerName'] = $contract['top_customer_name'];
            } else {
                continue;//合同编号不存在
            }

            //如果是老产品，需要替换为新产品id
            $productId = $authorize['ApplicationId'];
            if (isset($applications[$authorize['ApplicationId'] . $authorize['IsQdAdvanced']])) {
                $productId = $applications[$authorize['ApplicationId'] . $authorize['IsQdAdvanced']]['application_id'];
            }

            $data[$authorize['OrganizationId']]['RentContract'][$contractNumAndAuthorizeId[$authorize['ContractId']]]['ContractProduct'][] = [
                "ProductID"     => $productId, //产品ID
                "AuthorizedNum" => $authorize['TotalNum'], //授权数量
                "RentBeginDate" => $contractData[$authorize['ContractId']]['BeginOn'], //租期开始时间
                "RentEndDate"   => $contractData[$authorize['ContractId']]['EndOn'],//租期结束时间
            ];
        }

        // 去除数组键名
        $result = [];
        foreach ($data as $contract) {
            $allAuthorize = [];
            foreach ($contract['RentContract'] as $authorize) {
                $allAuthorize[] = $authorize;
            }
            $contract['RentContract'] = $allAuthorize;
            $result[] = $contract;
        }

        return $result;
    }

    /**
     * 数组转码
     * @param array $arr 要转码的数组
     * @param string $in_charset 输入的字符集
     * @param string $out_charset 输出的字符集
     * @return array
     */
    private function _arrayEncode(array $arr, $in_charset, $out_charset)
    {
        $result = [];
        foreach ($arr as $item) {
            $result[] = mb_convert_encoding($item, $in_charset, $out_charset);
        }

        return $result;
    }

    /**
     * 导出合同
     * @param string $status
     * @param string $property
     * @param string $keyword
     * @param string $areaId
     * @param string $signPeopleId
     * 参考：\common\services\myhtsq\ContractService\getContractList
     * 性能优化项：改用CSV格式导出，循环内的查询放到循环外
     * @return string
     */
    private function exportContractExcel($status = null, $property = null, $keyword = null, $areaId = null, $signPeopleId = null, $timeType = 0, $timeStart = '', $timeEnd = '')
    {
        try {
            set_time_limit(0);

            //数据源
            $data = ContractManageRepository::getContractListForExport($status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);

            //性能优化：把循环内的查数据移到循环外来批量获取以减少读取数据库次数
            $areaNameGroupById = $this->batchGetAreaName($data);
            $propertyNameGroupById = $this->batchGetPropertyName();
            $contractCategoryById = $this->batchGetContractCategory($data);
            $contractBigCategoryById = $this->batchGetContractBigCategory($data);
            $contractLittlerCategoryById = $this->batchGetContractLittlerCategory($data);
            $contractSignPeopleGroupById = $this->batchGetUserNameByIds($data);
            $contractSignPeopleDepartmentGroupById = $this->batchGetDepartmentByIds($data);
            $repaymentCompanyById = $this->batchGetRepaymentCompany($data);
            $contractIds = ArrayHelper::getColumn($data, 'contract_id');
            $contractBillingAmountSumGroupById = $this->batchGetBillingAmountSum($contractIds);
            $contractReceiptAmountSumGroupById = $this->batchGetReceiptAmountSum($contractIds);
            $contractReceivedAmountSumGroupById = $this->batchGetReceivedAmountSum($contractIds);
            $contractIsBadDebtGroupById = $this->batchGetIsBadDebt($contractIds);

            $contractCodes = ArrayHelper::getColumn($data, 'contract_code', false);
            $firstEstablishTimes = $this->batchGetFirstEstablishTime($contractCodes);
            $contractBeginOnEndOnGroupByCode = $this->batchGetBeginOnEndOn($contractCodes);

            //列标题
            $columnTitles = ['序号', '合同所属区域', '合同性质', '合同属性', '客户性质', '账套公司', '合同类别', '合同大类', '合同小类', '合同签署公司',
                '客户简称', '顶级客户简称', '签约客户全称', '合同编号','关联ERP合同编号','签约人', '签约人所属部门', '签约日期', '录入日期', '合同生效日期', '签约金额',
                '租用金额', '交付金额', '已开票金额', '已开收据金额', '已回款金额', '项目数', '产品名称', '产品标准总额合计', '租期开始时间', '租期结束时间', '账号开通时间',
                /*'合同成交折扣',*/'应结算金额',
                '结算金额', '返款金额', '返款状态', '返款时间', '返款类型', '服务机构',
                '是否坏账', /*'合同主责人', '主负责人所属ABU', '主负责人所属部门', '主负责人所属公司', '生效开始日期', '生效截止日期',*/ '备注'];

            //创建目录
            $exportDir = \Yii::getAlias("@runtime/web/xls/");
            \yii\helpers\FileHelper::createDirectory($exportDir);

            //创建文件
            $fileName = sprintf("hetong-data_%s.csv", \Yii::$app->user->identity->userguid);
            $allFilePath = $exportDir . $fileName;

            $fp = fopen($allFilePath, 'w');

            //boom头
            fwrite($fp, chr(0xEF) . chr(0xBB) . chr(0xBF));

            //写入标题
            fputcsv($fp, $columnTitles);

            if (!empty($data)) {
                $i = 1;
                foreach ($data as $key => $val) {
                    $areaName = $this->checkKeyIsset($areaNameGroupById, $val['area_id']);
                    $propertyName = $this->checkKeyIsset($propertyNameGroupById, $val['contract_property_id']);
                    $accountCompanyName = ContractAccountCompanyRepository::getContractAccountCompanyListByPropertyId($val['contract_property_id']);
                    $categoryName = $this->checkKeyIsset($contractCategoryById, $val['category_id']);
                    $bigCategoryName = $this->checkKeyIsset($contractBigCategoryById, $val['big_category_id']);
                    $littlerCategoryName = $this->checkKeyIsset($contractLittlerCategoryById, $val['littler_category_id']);
                    $signName = $this->checkKeyIsset($contractSignPeopleGroupById, $val['sign_people_id']);
                    $deptName = $this->checkKeyIsset($contractSignPeopleDepartmentGroupById, $val['sign_people_department_by']);
                    $billingAmount = $this->checkKeyIsset($contractBillingAmountSumGroupById, $val['contract_id']);
                    $receiptAmount = $this->checkKeyIsset($contractReceiptAmountSumGroupById, $val['contract_id']);
                    $receiveAmount = $this->checkKeyIsset($contractReceivedAmountSumGroupById, $val['contract_id']);
                    $productName = self::getProductNames($val['contract_id']);
                    $repayment_company = $this->checkKeyIsset($repaymentCompanyById, $val['repayment_company']);
//                    $belongName = $this->checkKeyIsset($contractSignPeopleGroupById, $val['belong_by']);
//                    $department_name = $this->checkKeyIsset($contractSignPeopleDepartmentGroupById, $val['department_by']);
                    $is_bad_debt = $this->checkKeyIsset($contractIsBadDebtGroupById, $val['contract_id']);
                    $principalInfo = $this->getPrincipalInfo($val['contract_id']);
                    $principalName = implode('，', ArrayHelper::getColumn($principalInfo, 'principal_name'));
                    $principal_abu_name = implode('，', ArrayHelper::getColumn($principalInfo, 'principal_abu_name'));
                    $principal_department_name = implode('，', ArrayHelper::getColumn($principalInfo, 'principal_department_name'));
                    $principal_area_name = implode('，', ArrayHelper::getColumn($principalInfo, 'principal_area_name'));
                    $principal_on = implode('，', ArrayHelper::getColumn($principalInfo, 'principal_on'));
                    $principal_end = implode('，', ArrayHelper::getColumn($principalInfo, 'principal_end'));

                    $beginOn = isset($contractBeginOnEndOnGroupByCode[$val['contract_code']]['BeginOn']) ? $contractBeginOnEndOnGroupByCode[$val['contract_code']]['BeginOn'] : '';
                    $endOn = isset($contractBeginOnEndOnGroupByCode[$val['contract_code']]['EndOn']) ? $contractBeginOnEndOnGroupByCode[$val['contract_code']]['EndOn'] : '';

                    //装拼正文内容
                    $contactArr = [
                        $i,//序号
                        empty($areaName) ? '' : $areaName,//合同所属区域
                        empty($propertyName) ? '' : $propertyName,//合同性质
                        self::getAttributeName($val['attribute_name']),//合同属性
                        $val['customer_property'] == 0 ? '开发商' : '代理商',//客户性质
                        empty($accountCompanyName) ? '' : $accountCompanyName[0]->account_company_name,//账套公司
                        empty($categoryName) ? '' : $categoryName,//合同类别
                        empty($bigCategoryName) ? '' : $bigCategoryName,//合同大类
                        empty($littlerCategoryName) ? '' : $littlerCategoryName,//合同小类
                        $val['company_name'], //合同签署公司
                        $val['customer_name'], //客户简称
                        $val['top_customer_name'], //顶级客户简称
                        $val['customer_full_name'], //签约客户全称
                        $val['contract_code'], //合同编号
                        $val['erp_contract_code'], //关联ERP合同编号
                        empty($signName) ? '' : $signName, //签约人
                        empty($deptName) ? '' : $deptName, //签约人所属部门
                        DateTimeHelper::getDate($val['sign_date']),//签约日期
                        DateTimeHelper::getDate($val['input_date']), //录入日期
                        DateTimeHelper::getDate($val['effect_date']), //合同生效日期
                        $val['sign_amount'], //签约金额
                        $val['rent_amount'], //租用金额
                        $val['delivery_amount'], //交付金额
                        empty($billingAmount) ? 0 : $billingAmount, //已开票金额
                        empty($receiptAmount) ? 0 : $receiptAmount, //已收据金额
                        empty($receiveAmount) ? 0 : $receiveAmount, //已回款金额
//                        $val['draw_project_numeric'], // 产品数
                        $val['project_numeric'], // 项目数
                        $productName,//产品名称
                        $val['application_amount'], //产品标准总额合计
                        self::getDateTimeString($beginOn), //租期开始时间
                        self::getDateTimeString($endOn), //租期结束时间
                        empty($firstEstablishTimes[$val['contract_code']][0]) ? '' : date('Y-m-d',strtotime($firstEstablishTimes[$val['contract_code']][0])), //账号开通时间
//                        round($val['contract_deal_discount'] * 100) . "%", // 合同成交折扣(%)
                        (strtotime($val['input_date'])<strtotime('2017-09-01'))?$val['balance_amount']:$val['income_amount'], //应结算金额
                        $val['balance_amount'], //结算金额
                        $val['back_amount'], //返款金额
                        $val['balance_status'] == 0 ? '未返款' : '已返款', //返款状态
                        self::getDateTimeString($val['repayment_time']), //返款时间
                        $val['repayment_type'] == 1 ? '现金' : '转预收', //返款类型
                        $repayment_company,//服务机构
//                        empty($belongName) ? '' : $belongName, //交付人员
//                        empty($department_name) ? '' : $department_name, //交付人员所属部门
//                        self::getDateTimeString($val['dely_on']), //交付时间
                        $is_bad_debt == 1 ? '是' : '否', //是否坏账
//                        $principalName === FALSE ? '' : $principalName, //合同主负责人
//                        $principal_abu_name, //所属ABU
//                        $principal_department_name, //所属部门
//                        $principal_area_name, //所属公司
//                        self::getDateTimeString($principal_on), //生效开始日期
//                        self::getDateTimeString($principal_end), //生效截止日期
                        $val['contract_remark'], //备注
                    ];

                    //写入正文
                    fputcsv($fp, $contactArr);

                    $i++;
                }
            }

            $key = $fileName;
            OSS::upload($key, $allFilePath);
            @unlink($allFilePath);
            $ossUrl = OSS::getUrl($key);

            return $ossUrl . '?t=' . StringHelper::uuid();

        } catch (\Exception $e) {
            Yii::error((string)$e);
            return $this->setAndReturn(__LINE__, '导出出错：' . $e->getMessage());
        }
    }

    private function checkKeyIsset($array, $key)
    {
        return isset($array[$key]) ? $array[$key] : '';
    }

    /**
     * 导出合同的产品信息
     * @param \PHPExcel $objPHPExcel
     * @param string $status
     * @param string $property
     * @param string $keyword
     * @param string $areaId
     * @param string $signPeopleId
     * 参考：\common\services\myhtsq\ContractService\getContractInfo->ContractApplicationRepository::getStandardContractApplicationByContractId
     * @param int $timeType
     * @param string $timeStart
     * @param string $timeEnd
     */
    private function exportContractProductExcel($objPHPExcel, $status = null, $property = null, $keyword = null, $areaId = null, $signPeopleId = null, $timeType = 0, $timeStart = '', $timeEnd = '')
    {
        $data = ContractManageRepository::getContractProductListForExport($status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);

        //设置当前的sheet
        $activeSheet = self::getActiveSheet($objPHPExcel);
        $activeSheet->setTitle('签约产品明细表');

        //设置列标题
        $columnTitles = ['序号', '合同所属区域', '合同性质', '合同属性', '客户性质', '账套公司', '合同类别', '合同大类', '合同小类', '合同签署公司',
            '客户简称', '顶级客户简称', '签约客户全称', '合同编号', '签约人', '签约日期', '录入日期', '签约金额', '租用金额', '交付金额', '产品名称',
            '标准单价(每项目、每年)', '项目数/短信条数', '租用周期(月)', '标准总额', '结算类型', '结算比例', '结算折扣', '结算分摊金额',
            '产品租金分摊金额', '签约分摊金额'];

        $columnIndex = 'A';
        foreach ($columnTitles as $key => $value) {
            $activeSheet->setCellValue($columnIndex . '1', $value);
            $activeSheet->getColumnDimension($columnIndex)->setWidth(15);
            $activeSheet->getStyle($columnIndex . '1')->getFont()->setBold(true);
            $columnIndex++;
        }

        //批量取数
        $areaNameGroupById = $this->batchGetAreaName($data);
        $propertyNameGroupById = $this->batchGetPropertyName();
        $contractCategoryById = $this->batchGetContractCategory($data);
        $contractBigCategoryById = $this->batchGetContractBigCategory($data);
        $contractLittlerCategoryById = $this->batchGetContractLittlerCategory($data);
        $contractSignPeopleGroupById = $this->batchGetUserNameByIds($data);

        //设置单元格的值
        if (!empty($data)) {
            $j = 2;
            foreach ($data as $key => $val) {
                $i = 'A';
                $activeSheet->setCellValue($i . $j, $j - 1); //序号
                $i++;
                $areaName = $this->checkKeyIsset($areaNameGroupById, $val['area_id']);
                $activeSheet->setCellValue($i . $j, $areaName === FALSE ? '' : $areaName); //合同所属区域
                $i++;
                $propertyName = $this->checkKeyIsset($propertyNameGroupById, $val['contract_property_id']);
                $activeSheet->setCellValue($i . $j, $propertyName === FALSE ? '' : $propertyName); //合同性质
                $i++;
                $attribute_name = self::getAttributeName($val['attribute_name']);
                $activeSheet->setCellValue($i . $j, $attribute_name); //合同属性
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_property'] == 0 ? '开发商' : '代理商'); //客户性质
                $i++;
                $accountCompayName = ContractAccountCompanyRepository::getContractAccountCompanyListByPropertyId($val['contract_property_id']);
                $activeSheet->setCellValue($i . $j, empty($accountCompayName) ? '' : $accountCompayName[0]->account_company_name); //账套公司
                $i++;
                $categoryName = $this->checkKeyIsset($contractCategoryById, $val['category_id']);
                $activeSheet->setCellValue($i . $j, $categoryName === FALSE ? '' : $categoryName); //合同类别
                $i++;
                $bigCategoryName = $this->checkKeyIsset($contractBigCategoryById, $val['big_category_id']);
                $activeSheet->setCellValue($i . $j, $bigCategoryName === FALSE ? '' : $bigCategoryName); //合同大类
                $i++;
                $littlerCategoryName = $this->checkKeyIsset($contractLittlerCategoryById, $val['littler_category_id']);
                $activeSheet->setCellValue($i . $j, $littlerCategoryName === FALSE ? '' : $littlerCategoryName); //合同小类
                $i++;
                $activeSheet->setCellValue($i . $j, $val['company_name']); //合同签署公司
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_name']); //客户简称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['top_customer_name']); //顶级客户简称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_full_name']); //签约客户全称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['contract_code']); //合同编号
                $i++;
                $signName = $this->checkKeyIsset($contractSignPeopleGroupById, $val['sign_people_id']);
                $activeSheet->setCellValue($i . $j, $signName); //签约人
                $i++;
                $activeSheet->setCellValue($i . $j, DateTimeHelper::getDate($val['sign_date'])); //签约日期
                $i++;
                $activeSheet->setCellValue($i . $j, DateTimeHelper::getDate($val['input_date'])); //录入日期
                $i++;
                $activeSheet->setCellValue($i . $j, $val['sign_amount']); //签约金额
                $i++;
                $activeSheet->setCellValue($i . $j, $val['rent_amount']); //租用金额
                $i++;
                $activeSheet->setCellValue($i . $j, $val['delivery_amount']); //交付金额
                $i++;
                $activeSheet->setCellValue($i . $j, $val['application_name']); //产品名称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['price_standard']); //标准单价(每项目、每年)'
                $i++;
                $activeSheet->setCellValue($i . $j, $val['authorization_numeric']); //项目数/短信条数
                $i++;
                $activeSheet->setCellValue($i . $j, $val['rent_period']); //租用周期(月)
                $i++;
                $activeSheet->setCellValue($i . $j, $val['amount']); //标准总额
                $i++;
                $activeSheet->setCellValue($i . $j, $this->formatSettlementTypeToChinese($val['settlement_type'])); //结算类型
                $i++;
                $activeSheet->setCellValue($i . $j, $val['settlement_scale']); //结算比例
                $i++;
                $activeSheet->setCellValue($i . $j, $val['discount']); //折扣
                $i++;
                $activeSheet->setCellValue($i . $j, $val['settlement_average_amount']); //结算分摊金额
                $i++;
                $activeSheet->setCellValue($i . $j, $val['product_average_amount']); //产品租金分摊金额
                $i++;
                $activeSheet->setCellValue($i . $j, $val['sign_average_amount']); //签约分摊金额
                $j++;
            }
        }

    }

    /**
     * 转换结算类型为中文
     * @param integer $settlementType 结算类型
     * @return string
     */
    private function formatSettlementTypeToChinese($settlementType)
    {
        switch ($settlementType){
            case 2:
                $settlementTypeForChinese = '折上折结算';
                break;
            case 3:
                $settlementTypeForChinese = '特价结算';
                break;
            //todo
            default:
                $settlementTypeForChinese = '标准结算';
        }
        return $settlementTypeForChinese;
    }



    /**
     * 获取应收款责任人
     * @param type $invoiceId
     * @return string
     */
    private function getPayeeNameByInvoiceId($invoiceId)
    {
        $payeeName = '';
        $receivableInfo = InvoiceReceivableRepository::getReceivableByInvoiceId($invoiceId);
        if (!empty($receivableInfo)) {
            $name = array_unique(ArrayHelper::getColumn($receivableInfo, 'payee_name'));
            $payeeName = implode(',', $name);
        }
        return $payeeName;
    }

    /**
     * 导出合同的收入信息
     * @param \PHPExcel $objPHPExcel
     * @param string $status
     * @param string $property
     * @param string $keyword
     * @param string $areaId
     * @param string $signPeopleId
     */
    private function exportContractNoPaymentExecl($objPHPExcel, $status = null, $property = null, $keyword = null, $areaId = null, $signPeopleId = null, $timeType = 0, $timeStart = '', $timeEnd = '')
    {
        $data = ContractManageRepository::getContractNoPaymentListForExport($status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);
        $badDebtList = InvoiceReceivableRepository::getBadDebtList();

        $badDebtAmountGroupBy = [];
        foreach ($badDebtList as $badDebt){
            if(isset($badDebtAmountGroupBy[$badDebt['invoice_id']])){
                $badDebtAmountGroupBy[$badDebt['invoice_id']] += $badDebt['cur_billing_amount'];
            }else{
                $badDebtAmountGroupBy[$badDebt['invoice_id']] = $badDebt['cur_billing_amount'];
            }
        }

        //未回款金额要减去对应的应收款标记为坏账的开票金额
        foreach($data as $key => $invoice){
            //未回款金额
            $data[$key]['no_pay_amount'] = $invoice['invoice_amount'] - $invoice['payment_amount'];

            if(array_key_exists($invoice['invoice_id'], $badDebtAmountGroupBy)){
                $data[$key]['no_pay_amount'] = $data[$key]['no_pay_amount'] - $badDebtAmountGroupBy[$invoice['invoice_id']];
            }

            //移除未回款金额小于等于0的
            if($data[$key]['no_pay_amount'] <= 0){
                unset($data[$key]);
            }
        }
        $data = array_values($data);

        //设置当前的sheet
        $activeSheet = self::getActiveSheet($objPHPExcel);
        $activeSheet->setTitle('已开票未回款明细表');

        //设置列标题
        $columnTitles = ['开票单位', '合同所属区域', '客户简称', '签约客户全称', '签约人', '签约日期', '签约金额', '发票类别', '开票日期', '开票金额',
            '已回款金额', '未回款金额', '发票名称', '发票代码', '发票编号', '发票申请人', '对应合同', '应收款责任人', '发票类型'];

        $columnIndex = 'A';
        foreach ($columnTitles as $key => $value) {
            $activeSheet->setCellValue($columnIndex . '1', $value);
            $activeSheet->getColumnDimension($columnIndex)->setWidth(15);
            $activeSheet->getStyle($columnIndex . '1')->getFont()->setBold(true);
            $columnIndex++;
        }

        //批量取数
        $invoiceCompanyName = $this->batchGetInvoiceBuName($data);
        $areaNameGroupById = $this->batchGetAreaName($data);
        $contractSignPeopleGroupById = $this->batchGetUserNameByIds($data);

        /** @var  $invoiceService InvoiceService */
        $invoiceService = Yii::createObject(InvoiceService::className());

        //设置单元格的值
        if (!empty($data)) {
            $j = 2;
            foreach ($data as $key => $val) {
                $i = 'A';
                $companyName = $this->checkKeyIsset($invoiceCompanyName, $val['invoice_company_id']);
                $activeSheet->setCellValue($i . $j, $companyName === FALSE ? '' : $companyName); //开票单位
                $i++;
                $areaName = $this->checkKeyIsset($areaNameGroupById, $val['area_id']);
                $activeSheet->setCellValue($i . $j, $areaName === FALSE ? '' : $areaName); //合同所属区域
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_name']); //客户简称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_full_name']); //签约客户全称
                $i++;
                $signName = $this->checkKeyIsset($contractSignPeopleGroupById, $val['sign_people_id']);
                $activeSheet->setCellValue($i . $j, $signName); //签约人
                $i++;
                $activeSheet->setCellValue($i . $j, DateTimeHelper::getDate($val['sign_date'])); //签约日期
                $i++;
                $activeSheet->setCellValue($i . $j, $val['sign_amount']); //签约金额
                $i++;
                $activeSheet->setCellValue($i . $j, $invoiceService->transformInvoiceCategoryToChinese($val['invoice_category'])); //发票类别
                $i++;
                $activeSheet->setCellValue($i . $j, $val['invoice_date']); //开票日期
                $i++;
                $activeSheet->setCellValue($i . $j, $val['invoice_amount']); //开票金额
                $i++;
                $activeSheet->setCellValue($i . $j, $val['payment_amount']); //已回款金额
                $i++;
                $activeSheet->setCellValue($i . $j, $val['no_pay_amount']); //未回款金额
                $i++;
                $activeSheet->setCellValue($i . $j, $val['invoice_name']); //发票名称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['invoice_code']); //发票代码
                $i++;
                $activeSheet->setCellValue($i . $j, $val['invoice_no']); //发票编号
                $i++;
                $proposerName = $this->checkKeyIsset($contractSignPeopleGroupById, $val['proposer_id']);
                $activeSheet->setCellValue($i . $j, $proposerName); //发票申请人
                $i++;
                $activeSheet->setCellValue($i . $j, $val['contract_code']); //对应合同
                $i++;
                $payeeName = $this->getPayeeNameByInvoiceId($val['invoice_id']);
                $activeSheet->setCellValue($i . $j, $payeeName); //应收款责任人
                $i++;
                $activeSheet->setCellValue($i . $j, $invoiceService->transformInvoceTypeToChinese($val['invoice_type'])); //发票类型

                $j++;
            }
        }
    }

    /**
     * 导出合同的收入信息
     * @param \PHPExcel $objPHPExcel
     * @param string $status
     * @param string $property
     * @param string $keyword
     * @param string $areaId
     * @param string $signPeopleId
     */
    private function exportContractRevenueExecl($objPHPExcel, $status = null, $property = null, $keyword = null, $areaId = null, $signPeopleId = null, $timeType = 0, $timeStart = '', $timeEnd = '')
    {
        $data = ContractManageRepository::getContractRevenueListForExport($status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);

        //设置当前的sheet
        $activeSheet = self::getActiveSheet($objPHPExcel);
        $activeSheet->setTitle('收入明细表');

        //设置列标题
        $columnTitles = ['客户名称', '客户简称', '合同签署公司', '签约日期', '录入日期', '合同编号', '收入项编码', '账套公司',
            '合同性质', '合同类别', '合同小类', '合同所属区域', '核算收入类别', '收入项金额', '租期开始时间', '租期结束时间'
        ];

        $columnIndex = 'A';
        foreach ($columnTitles as $key => $value) {
            $activeSheet->setCellValue($columnIndex . '1', $value);
            $activeSheet->getColumnDimension($columnIndex)->setWidth(15);
            $activeSheet->getStyle($columnIndex . '1')->getFont()->setBold(true);
            $columnIndex++;
        }

        //批量取数
        $propertyNameGroupById = $this->batchGetPropertyName();
        $contractCategoryById = $this->batchGetContractCategory($data);
        $contractLittlerCategoryById = $this->batchGetContractLittlerCategory($data);

        //设置单元格的值
        if (!empty($data)) {
            $j = 2;
            foreach ($data as $key => $val) {
                $i = 'A';
                $activeSheet->setCellValue($i . $j, $val['customer_full_name']); //客户名称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_name']); //客户简称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['company_name']); //签约公司
                $i++;
                $activeSheet->setCellValue($i . $j, StringHelper::formatDate($val['sign_date'], 'Y-m-d')); //签约时间
                $i++;
                $activeSheet->setCellValue($i . $j, StringHelper::formatDate($val['input_date'], 'Y-m-d')); //录入时间
                $i++;
                $activeSheet->setCellValue($i . $j, $val['contract_code']); //合同编号
                $i++;
                $activeSheet->setCellValue($i . $j, $val['income_code']); //收入项编码
                $i++;
                $accountCompayName = ContractAccountCompanyRepository::getContractAccountCompanyListByPropertyId($val['contract_property_id']);
                $activeSheet->setCellValue($i . $j, empty($accountCompayName) ? '' : $accountCompayName[0]->account_company_name); //账套公司
                $i++;
                $propertyName = $this->checkKeyIsset($propertyNameGroupById, $val['contract_property_id']);
                $activeSheet->setCellValue($i . $j, $propertyName === FALSE ? '' : $propertyName); //合同性质
                $i++;
                $categoryName = $this->checkKeyIsset($contractCategoryById, $val['category_id']);
                $activeSheet->setCellValue($i . $j, $categoryName === FALSE ? '' : $categoryName); //合同类别
                $i++;
                $littlerCategoryName = $this->checkKeyIsset($contractLittlerCategoryById, $val['littler_category_id']);
                $activeSheet->setCellValue($i . $j, $littlerCategoryName === FALSE ? '' : $littlerCategoryName); //合同小类
                $i++;
                $activeSheet->setCellValue($i . $j, $val['area_name']); //合同所属区域
                $i++;
                $activeSheet->setCellValue($i . $j, $val['type_name']); //核算收入类别
                $i++;
                $activeSheet->setCellValue($i . $j, $val['amount']); //收入项金额
                $i++;
                $activeSheet->setCellValue($i . $j, self::getDateTimeString($val['BeginOn'])); //租期开始时间
                $i++;
                $activeSheet->setCellValue($i . $j, self::getDateTimeString($val['EndOn'])); //租期结束时间
                $i++;
                $j++;
            }
        }
    }

    /**
     * 导出合同的交付业绩明细表信息
     * @param \PHPExcel $objPHPExcel
     * @param string $status
     * @param string $property
     * @param string $keyword
     * @param string $areaId
     * @param string $signPeopleId
     */
    private function exportContractDelyExecl($objPHPExcel, $status = null, $property = null, $keyword = null, $areaId = null, $signPeopleId = null , $timeType = 0, $timeStart = '', $timeEnd = '')
    {
        $data = ContractManageRepository::getContractDelyListForExport($status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);

        //设置当前的sheet
        $activeSheet = self::getActiveSheet($objPHPExcel);
        $activeSheet->setTitle('交付业绩明细表');

        //设置列标题
        $columnTitles = [
            '序号', '合同所属区域', '合同性质', '合同属性', '客户性质', '账套公司', '合同类别', '合同大类', '合同小类', '合同签署公司',
            '客户简称', '顶级客户简称', '签约客户全称', '合同编号', '签约人', '签约人所属部门', '签约日期', '录入日期', '签约金额', '交付业绩属性',
            '回款金额', '交付业绩金额', '交付业绩归属时间', '交付业绩归属人', '交付业绩所属部门', '交付业绩所属区域', '项目交付时间'];

        $columnIndex = 'A';
        foreach ($columnTitles as $key => $value) {
            $activeSheet->setCellValue($columnIndex . '1', $value);
            $activeSheet->getColumnDimension($columnIndex)->setWidth(15);
            $activeSheet->getStyle($columnIndex . '1')->getFont()->setBold(true);
            $columnIndex++;
        }

        //批量取数
        $areaNameGroupById = $this->batchGetAreaName($data);
        $propertyNameGroupById = $this->batchGetPropertyName();
        $contractCategoryById = $this->batchGetContractCategory($data);
        $contractBigCategoryById = $this->batchGetContractBigCategory($data);
        $contractLittlerCategoryById = $this->batchGetContractLittlerCategory($data);
        $contractSignPeopleGroupById = $this->batchGetUserNameByIds($data);
        $contractSignPeopleDepartmentGroupById = $this->batchGetDepartmentByIds($data);

        //设置单元格的值
        if (!empty($data)) {
            $j = 2;
            foreach ($data as $key => $val) {
                $i = 'A';
                $activeSheet->setCellValue($i . $j, $j - 1); //序号
                $i++;
                $areaName = $this->checkKeyIsset($areaNameGroupById, $val['area_id']);
                $activeSheet->setCellValue($i . $j, $areaName === FALSE ? '' : $areaName); //合同所属区域
                $i++;
                $propertyName = $this->checkKeyIsset($propertyNameGroupById, $val['contract_property_id']);
                $activeSheet->setCellValue($i . $j, $propertyName === FALSE ? '' : $propertyName); //合同性质
                $i++;
                $attribute_name = self::getAttributeName($val['attribute_name']);
                $activeSheet->setCellValue($i . $j, $attribute_name); //合同属性
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_property'] == 0 ? '开发商' : '代理商'); //客户性质
                $i++;
                $accountCompayName = ContractAccountCompanyRepository::getContractAccountCompanyListByPropertyId($val['contract_property_id']);
                $activeSheet->setCellValue($i . $j, empty($accountCompayName) ? '' : $accountCompayName[0]->account_company_name); //账套公司
                $i++;
                $categoryName = $this->checkKeyIsset($contractCategoryById, $val['category_id']);
                $activeSheet->setCellValue($i . $j, $categoryName === FALSE ? '' : $categoryName); //合同类别
                $i++;
                $bigCategoryName = $this->checkKeyIsset($contractBigCategoryById, $val['big_category_id']);
                $activeSheet->setCellValue($i . $j, $bigCategoryName === FALSE ? '' : $bigCategoryName); //合同大类
                $i++;
                $littlerCategoryName = $this->checkKeyIsset($contractLittlerCategoryById, $val['littler_category_id']);
                $activeSheet->setCellValue($i . $j, $littlerCategoryName === FALSE ? '' : $littlerCategoryName); //合同小类
                $i++;
                $activeSheet->setCellValue($i . $j, $val['company_name']); //合同签署公司
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_name']); //客户简称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['top_customer_name']); //顶级客户简称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_full_name']); //签约客户全称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['contract_code']); //合同编号
                $i++;
                $signName = $this->checkKeyIsset($contractSignPeopleGroupById, $val['sign_people_id']);
                $activeSheet->setCellValue($i . $j, $signName); //签约人
                $i++;
                $deptName = $this->checkKeyIsset($contractSignPeopleDepartmentGroupById, $val['sign_people_department_by']);
                $activeSheet->setCellValue($i . $j, $deptName === FALSE ? '' : $deptName); //签约人所属部门
                $i++;
                $activeSheet->setCellValue($i . $j, DateTimeHelper::getDate($val['sign_date'])); //签约日期
                $i++;
                $activeSheet->setCellValue($i . $j, DateTimeHelper::getDate($val['input_date'])); //录入日期
                $i++;
                $activeSheet->setCellValue($i . $j, $val['sign_amount']); //签约金额
                $i++;
                $sd_attribute_name = self::getAttributeName($val['sd_attribute_name']);
                $activeSheet->setCellValue($i . $j, $sd_attribute_name); //交付业绩属性
                $i++;
                $receiveAmount = ContractReceivableRepository::getReceivedAmountSum($val['contract_id']);
                $activeSheet->setCellValue($i . $j, $receiveAmount); //回款金额
                $i++;
                $activeSheet->setCellValue($i . $j, $val['dely_amount']); //交付业绩金额
                $i++;
                $activeSheet->setCellValue($i . $j, self::getDateTimeString($val['dely_on'])); //交付业绩归属时间
                $i++;
                $belongName = $this->checkKeyIsset($contractSignPeopleGroupById, $val['belong_by']);
                $activeSheet->setCellValue($i . $j, $belongName === FALSE ? '' : $belongName); //交付业绩归属人
                $i++;
                $delyDeptName = $this->checkKeyIsset($contractSignPeopleDepartmentGroupById, $val['department_by']);
                $activeSheet->setCellValue($i . $j, $delyDeptName === FALSE ? '' : $delyDeptName); //交付业绩所属部门
                $i++;
                $signAreaName = $this->checkKeyIsset($contractSignPeopleDepartmentGroupById, $val['area_by']);
                $activeSheet->setCellValue($i . $j, $signAreaName === FALSE ? '' : $signAreaName); //交付业绩所属区域
                $i++;
                $activeSheet->setCellValue($i . $j, self::getDateTimeString($val['dely_belong_on'])); //项目交付时间

                $j++;
            }
        }
    }


    /**
     * 导出联营区域未上传标的物明细表
     * @param \PHPExcel $objPHPExcel
     * @param string $status
     * @param string $property
     * @param string $keyword
     * @param string $areaId
     * @param string $signPeopleId
     */
    private function exportContractNoUploadTypeExecl($objPHPExcel, $status = null, $property = null, $keyword = null, $areaId = null, $signPeopleId = null, $timeType = 0, $timeStart = '', $timeEnd = '')
    {
        $data = ContractManageRepository::getContractNoUploadTypeForExport($status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);

        //设置当前的sheet
        $activeSheet = self::getActiveSheet($objPHPExcel);
        //$activeSheet->setTitle('联营区域未上传标的物明细表');
        $activeSheet->setTitle('代理合同未上传标的物明细表');

        //设置列标题
        $columnTitles = [
            '序号', '合同所属区域', '合同编号', '签约日期', '录入日期', '客户简称', '签约金额', '结算金额', '合同性质', '产品信息', '有无标的物'];

        $columnIndex = 'A';
        foreach ($columnTitles as $key => $value) {
            $activeSheet->setCellValue($columnIndex . '1', $value);
            $activeSheet->getColumnDimension($columnIndex)->setWidth(15);
            $activeSheet->getStyle($columnIndex . '1')->getFont()->setBold(true);
            $columnIndex++;
        }

        //批量取数
        $areaNameGroupById = $this->batchGetAreaName($data);
        $propertyNameGroupById = $this->batchGetPropertyName();
        $contractIds = ArrayHelper::getColumn($data, 'contract_id');
        $applicationNames =$this->batchGetApplicationName($contractIds);

        //设置单元格的值
        if (!empty($data)) {
            $j = 2;
            foreach ($data as $key => $val) {
                if(!in_array($val['contract_property_id'], [self::MY_ZS, self::MY_LY, self::LY_YKJS])){
                    continue;
                }
                $i = 'A';
                $activeSheet->setCellValue($i . $j, $j - 1); //序号
                $i++;
                $areaName = $this->checkKeyIsset($areaNameGroupById, $val['area_id']);
                $activeSheet->setCellValue($i . $j, $areaName === FALSE ? '' : $areaName); //合同所属区域
                $i++;
                $activeSheet->setCellValue($i . $j, $val['contract_code']); //合同编号
                $i++;
                $activeSheet->setCellValue($i . $j, DateTimeHelper::getDate($val['sign_date'])); //签约日期
                $i++;
                $activeSheet->setCellValue($i . $j, DateTimeHelper::getDate($val['input_date'])); //录入日期
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_name']); //客户简称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['sign_amount']); //签约金额
                $i++;
                $activeSheet->setCellValue($i . $j, $val['balance_amount']); //交付业绩金额
                $i++;
                $propertyName = $this->checkKeyIsset($propertyNameGroupById, $val['contract_property_id']);
                $activeSheet->setCellValue($i . $j, $propertyName === FALSE ? '' : $propertyName); //合同性质
                $i++;
                $activeSheet->setCellValue($i . $j, implode(',', $applicationNames[$val['contract_id']])); //产品信息
                $i++;
                $activeSheet->setCellValue($i . $j, $this->multipleComparisons($val['document_type_4'],count($this->getAuthorizationSummary($val['contract_code'])))); //产品信息
                $i++;

                $j++;
            }
        }
    }

    /**
     * 导出合同的应收款项信息
     * @param \PHPExcel $objPHPExcel
     * @param string $status
     * @param string $property
     * @param string $keyword
     * @param string $areaId
     * @param string $signPeopleId
     */
    private function exportContractReceivableExecl($objPHPExcel, $status = null, $property = null, $keyword = null, $areaId = null, $signPeopleId = null, $timeType = 0, $timeStart = '', $timeEnd = '')
    {
        $data = ContractManageRepository::getContractReceivableListForExport($status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);
        //设置当前的sheet
        $activeSheet = self::getActiveSheet($objPHPExcel);
        $activeSheet->setTitle('应收款项明细表');

        //设置列标题
        $columnTitles = [
            '序号', '合同所属区域', '合同性质', '合同属性', '客户性质', '账套公司', '合同类别', '合同大类', '合同小类', '合同签署公司',
            '客户简称', '顶级客户简称', '签约客户全称', '合同编号', '签约人', '签约人所属部门', '签约日期', '录入日期', '签约金额',
            '款项名称', '款项小类', '收入类型', '应收金额', '应收日期', '收款责任人', '已开票金额', '已收金额', '未收金额', '是否坏账', '付款条件'];

        $columnIndex = 'A';
        foreach ($columnTitles as $key => $value) {
            $activeSheet->setCellValue($columnIndex . '1', $value);
            $activeSheet->getColumnDimension($columnIndex)->setWidth(15);
            $activeSheet->getStyle($columnIndex . '1')->getFont()->setBold(true);
            $columnIndex++;
        }

        //批量取数
        $areaNameGroupById = $this->batchGetAreaName($data);
        $propertyNameGroupById = $this->batchGetPropertyName();
        $contractCategoryById = $this->batchGetContractCategory($data);
        $contractBigCategoryById = $this->batchGetContractBigCategory($data);
        $contractLittlerCategoryById = $this->batchGetContractLittlerCategory($data);
        $contractSignPeopleGroupById = $this->batchGetUserNameByIds($data);
        $contractSignPeopleDepartmentGroupById = $this->batchGetDepartmentByIds($data);

        //设置单元格的值
        if (!empty($data)) {
            $j = 2;
            foreach ($data as $key => $val) {
                $i = 'A';
                $activeSheet->setCellValue($i . $j, $j - 1); //序号
                $i++;
                $areaName = $this->checkKeyIsset($areaNameGroupById, $val['area_id']);
                $activeSheet->setCellValue($i . $j, $areaName === FALSE ? '' : $areaName); //合同所属区域
                $i++;
                $propertyName = $this->checkKeyIsset($propertyNameGroupById, $val['contract_property_id']);
                $activeSheet->setCellValue($i . $j, $propertyName === FALSE ? '' : $propertyName); //合同性质
                $i++;
                $attribute_name = self::getAttributeName($val['attribute_name']);
                $activeSheet->setCellValue($i . $j, $attribute_name); //合同属性
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_property'] == 0 ? '开发商' : '代理商'); //客户性质
                $i++;
                $accountCompayName = ContractAccountCompanyRepository::getContractAccountCompanyListByPropertyId($val['contract_property_id']);
                $activeSheet->setCellValue($i . $j, empty($accountCompayName) ? '' : $accountCompayName[0]->account_company_name); //账套公司
                $i++;
                $categoryName = $this->checkKeyIsset($contractCategoryById, $val['category_id']);
                $activeSheet->setCellValue($i . $j, $categoryName === FALSE ? '' : $categoryName); //合同类别
                $i++;
                $bigCategoryName = $this->checkKeyIsset($contractBigCategoryById, $val['big_category_id']);
                $activeSheet->setCellValue($i . $j, $bigCategoryName === FALSE ? '' : $bigCategoryName); //合同大类
                $i++;
                $littlerCategoryName = $this->checkKeyIsset($contractLittlerCategoryById, $val['littler_category_id']);
                $activeSheet->setCellValue($i . $j, $littlerCategoryName === FALSE ? '' : $littlerCategoryName); //合同小类
                $i++;
                $activeSheet->setCellValue($i . $j, $val['company_name']); //合同签署公司
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_name']); //客户简称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['top_customer_name']); //顶级客户简称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_full_name']); //签约客户全称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['contract_code']); //合同编号
                $i++;
                $signName = $this->checkKeyIsset($contractSignPeopleGroupById, $val['sign_people_id']);
                $activeSheet->setCellValue($i . $j, $signName); //签约人
                $i++;
                $deptName = $this->checkKeyIsset($contractSignPeopleDepartmentGroupById, $val['sign_people_department_by']);
                $activeSheet->setCellValue($i . $j, $deptName === FALSE ? '' : $deptName); //签约人所属部门
                $i++;
                $activeSheet->setCellValue($i . $j, DateTimeHelper::getDate($val['sign_date'])); //签约日期
                $i++;
                $activeSheet->setCellValue($i . $j, DateTimeHelper::getDate($val['input_date'])); //录入日期
                $i++;
                $activeSheet->setCellValue($i . $j, $val['sign_amount']); //签约金额
                $i++;
                $activeSheet->setCellValue($i . $j, $val['receivable_item_name']); //款项名称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['money_category_item_name']); //款项小类
                $i++;
                $activeSheet->setCellValue($i . $j, $val['revenue_type_name']); //收入类型
                $i++;
                $activeSheet->setCellValue($i . $j, $val['receivable_amount']); //应收金额
                $i++;
                $activeSheet->setCellValue($i . $j, self::getDateTimeString($val['receivable_date'])); //应收日期
                $i++;
                $activeSheet->setCellValue($i . $j, $val['payee_name']); //收款责任人
                $i++;
                $activeSheet->setCellValue($i . $j, $val['billing_amount']); //已开票金额
                $i++;
                $activeSheet->setCellValue($i . $j, $val['received_amount']); //已回款金额
                $i++;
                $activeSheet->setCellValue($i . $j, $val['receivable_amount'] - $val['received_amount']);//未收金额
                $i++;
                $activeSheet->setCellValue($i . $j, $val['is_bad_debt'] == 1 ? '是' : '否');//是否坏账
                $i++;
                $activeSheet->setCellValue($i . $j, $val['payment_condition']); //付款条件
                $i++;

                $j++;
            }
        }
    }

    /**
     * 导出合同的发票信息
     * @param \PHPExcel $objPHPExcel
     * @param string $status
     * @param string $property
     * @param string $keyword
     * @param string $areaId
     * @param string $signPeopleId
     */
    private function exportContractInvoiceExecl($objPHPExcel, $status = null, $property = null, $keyword = null, $areaId = null, $signPeopleId = null)
    {
        $data = ContractManageRepository::getContractInvoiceListForExport($status, $property, $keyword, $areaId, $signPeopleId);

        //设置当前的sheet
        $activeSheet = self::getActiveSheet($objPHPExcel);
        $activeSheet->setTitle('发票');

        //设置列标题
        $columnTitles = ['客户名称', '客户简称', '合同编号', '合同所属区域', '票据代码', '票据号码', '开票金额', '开票单位', '开票时间', '客户名称', '对应回款', '已回款金额', '是否遗失', '是否红冲', '是否收据'];
        $columnIndex = 'A';
        foreach ($columnTitles as $key => $value) {
            $activeSheet->setCellValue($columnIndex . '1', $value);
            $activeSheet->getColumnDimension($columnIndex)->setWidth(15);
            $activeSheet->getStyle($columnIndex . '1')->getFont()->setBold(true);
            $columnIndex++;
        }

        //设置单元格的值
        if (!empty($data)) {
            $j = 2;
            foreach ($data as $key => $val) {
                $i = 'A';
                //$activeSheet->setCellValue($i . $j, $val['invoice_id']);
                //$i++;
                $activeSheet->setCellValue($i . $j, $val['customer_full_name']); //客户名称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_name']); //客户简称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['contract_code']); //合同编号
                $i++;
                $activeSheet->setCellValue($i . $j, $val['area_name']); //合同所属区域
                $i++;
                $activeSheet->setCellValue($i . $j, $val['invoice_code']);
                $i++;
                $activeSheet->setCellValue($i . $j, $val['invoice_no']);
                $i++;
                $activeSheet->setCellValue($i . $j, $val['invoice_amount']);
                $i++;
                $activeSheet->setCellValue($i . $j, $val['BUName']);
                $i++;
                $activeSheet->setCellValue($i . $j, self::getDateTimeString($val['invoice_date']));
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_name']);
                $i++;
                $activeSheet->setCellValue($i . $j, $val['receivables_amount']);
                $i++;
                $activeSheet->setCellValue($i . $j, $val['payment_amount']);
                $i++;
                $activeSheet->setCellValue($i . $j, $val['is_lose'] == 1 ? '是' : '否');
                $i++;
                $activeSheet->setCellValue($i . $j, $val['is_red_invoice'] == 1 ? '是' : '否');
                $i++;
                $activeSheet->setCellValue($i . $j, $val['is_receipt'] == 1 ? '是' : '否');
                $i++;

                $j++;
            }
        }

    }

    /**
     * 获取对应的发票
     * @param type $payment_id
     * @return type
     */
    private static function getBillingInvoiceNo($payment_id)
    {
        $billing_invoice_no = '';
        $invoicePayments = InvoicePaymentRepository::getInoicePaymentByPaymentId($payment_id);
        if (!empty($invoicePayments)) {
            foreach ($invoicePayments as $k1 => $v1) {
                $billing_invoice_no = $v1['invoice_no'] . ';' . $billing_invoice_no;
            }
            $billing_invoice_no = substr($billing_invoice_no, 0, strlen($billing_invoice_no) - 1);
        }
        return $billing_invoice_no;
    }

    /**
     * 导出合同的回款信息
     * @param \PHPExcel $objPHPExcel
     * @param string $status
     * @param string $property
     * @param string $keyword
     * @param string $areaId
     * @param string $signPeopleId
     * @param int $timeType
     * @param string $timeStart
     * @param string $timeEnd
     */
    private function exportContractPaymentExecl($objPHPExcel, $status = null, $property = null, $keyword = null, $areaId = null, $signPeopleId = null, $timeType = 0, $timeStart = '', $timeEnd = '')
    {
        $data = ContractManageRepository::getContractPaymentListForExport($status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);

        //设置当前的sheet
        $activeSheet = self::getActiveSheet($objPHPExcel);
        $activeSheet->setTitle('合同回款明细表');

        //设置列标题
        $columnTitles = ['序号', '合同所属区域', '合同性质', '合同属性', '客户性质', '账套公司', '合同类别', '合同大类', '合同小类', '合同签署公司',
            '客户简称', '顶级客户简称', '签约客户全称', '合同编号', '关联ERP合同编号', '财务编码', '签约人', '签约人所属部门', '签约日期', '录入日期', '签约金额',
            '结算金额', '实收时间', '款项归档时间', '实收总额', '实收编号', '收款账户', '付款客户名称', '产品名称', '对应发票'
        ];

        $columnIndex = 'A';
        foreach ($columnTitles as $key => $value) {
            $activeSheet->setCellValue($columnIndex . '1', $value);
            $activeSheet->getColumnDimension($columnIndex)->setWidth(15);
            $activeSheet->getStyle($columnIndex . '1')->getFont()->setBold(true);
            $columnIndex++;
        }

        //批量取数
        $areaNameGroupById = $this->batchGetAreaName($data);
        $propertyNameGroupById = $this->batchGetPropertyName();
        $contractCategoryById = $this->batchGetContractCategory($data);
        $contractBigCategoryById = $this->batchGetContractBigCategory($data);
        $contractLittlerCategoryById = $this->batchGetContractLittlerCategory($data);
        $contractSignPeopleGroupById = $this->batchGetUserNameByIds($data);
        $contractSignPeopleDepartmentGroupById = $this->batchGetDepartmentByIds($data);

        //设置单元格的值
        if (!empty($data)) {
            $j = 2;
            foreach ($data as $key => $val) {
                $i = 'A';
                $activeSheet->setCellValue($i . $j, $j - 1); //序号
                $i++;
                $areaName = $this->checkKeyIsset($areaNameGroupById, $val['area_id']);
                $activeSheet->setCellValue($i . $j, $areaName === FALSE ? '' : $areaName); //合同所属区域
                $i++;
                $propertyName = $this->checkKeyIsset($propertyNameGroupById, $val['contract_property_id']);
                $activeSheet->setCellValue($i . $j, $propertyName === FALSE ? '' : $propertyName); //合同性质
                $i++;
                $attribute_name = self::getAttributeName($val['attribute_name']);
                $activeSheet->setCellValue($i . $j, $attribute_name); //合同属性
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_property'] == 0 ? '开发商' : '代理商'); //客户性质
                $i++;
                $accountCompayName = ContractAccountCompanyRepository::getContractAccountCompanyListByPropertyId($val['contract_property_id']);
                $activeSheet->setCellValue($i . $j, empty($accountCompayName) ? '' : $accountCompayName[0]->account_company_name); //账套公司
                $i++;
                $categoryName = $this->checkKeyIsset($contractCategoryById, $val['category_id']);
                $activeSheet->setCellValue($i . $j, $categoryName === FALSE ? '' : $categoryName); //合同类别
                $i++;
                $bigCategoryName = $this->checkKeyIsset($contractBigCategoryById, $val['big_category_id']);
                $activeSheet->setCellValue($i . $j, $bigCategoryName === FALSE ? '' : $bigCategoryName); //合同大类
                $i++;
                $littlerCategoryName = $this->checkKeyIsset($contractLittlerCategoryById, $val['littler_category_id']);
                $activeSheet->setCellValue($i . $j, $littlerCategoryName === FALSE ? '' : $littlerCategoryName); //合同小类
                $i++;
                $activeSheet->setCellValue($i . $j, $val['company_name']); //合同签署公司
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_name']); //客户简称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['top_customer_name']); //顶级客户简称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_full_name']); //签约客户全称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['contract_code']); //合同编号
                $i++;
                $activeSheet->setCellValue($i . $j, in_array($val['contract_property_id'], [self::MY_ZS, self::YK_ZS]) ? $val['erp_contract_code'] : ''); //关联ERP合同编号
                $i++;
                $activeSheet->setCellValue($i . $j, $val['finance_code']); //财务编码
                $i++;
                $signName = $this->checkKeyIsset($contractSignPeopleGroupById, $val['sign_people_id']);
                $activeSheet->setCellValue($i . $j, $signName); //签约人
                $i++;
                $deptName = $this->checkKeyIsset($contractSignPeopleDepartmentGroupById, $val['sign_people_department_by']);
                $activeSheet->setCellValue($i . $j, $deptName === FALSE ? '' : $deptName); //签约人所属部门
                $i++;
                $activeSheet->setCellValue($i . $j, DateTimeHelper::getDate($val['sign_date'])); //签约日期
                $i++;
                $activeSheet->setCellValue($i . $j, DateTimeHelper::getDate($val['input_date'])); //录入日期
                $i++;
                $activeSheet->setCellValue($i . $j, $val['sign_amount']); //签约金额
                $i++;
                $activeSheet->setCellValue($i . $j, $val['balance_amount']); //结算金额
                $i++;
                $activeSheet->setCellValue($i . $j, self::getDateTimeString($val['payment_date'])); //实收时间
                $i++;
                $activeSheet->setCellValue($i . $j, self::getDateTimeString($val['payment_input_date'])); //款项归档时间
                $i++;
                $activeSheet->setCellValue($i . $j, $val['payment_amount']); //实收总额
                $i++;
                $activeSheet->setCellValue($i . $j, $val['payment_code']); //实收编号
                $i++;
                $activeSheet->setCellValue($i . $j, $val['receivables_account_name']); //收款账户
                $i++;
                $activeSheet->setCellValue($i . $j, $val['payment_account_name']); //付款客户名称
                $i++;
                $productName = self::getProductNames($val['contract_id']);
                $activeSheet->setCellValue($i . $j, $productName); //产品名称
                $i++;
                $billing_invoice_no = self::getBillingInvoiceNo($val['payment_id']);
                $activeSheet->setCellValue($i . $j, $billing_invoice_no); //对应发票

                $j++;
            }
        }
    }

    /**
     * 导出合同的签约业绩信息
     * @param \PHPExcel $objPHPExcel
     * @param string $status
     * @param string $property
     * @param string $keyword
     * @param string $areaId
     * @param string $signPeopleId
     */
    private function exportContractSignAchievementExecl($objPHPExcel, $status = null, $property = null, $keyword = null, $areaId = null, $signPeopleId = null, $timeType = 0, $timeStart = '', $timeEnd = '')
    {
        $data = ContractManageRepository::getContractSignAchievementListForExport($status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);

        //设置当前的sheet
        $activeSheet = self::getActiveSheet($objPHPExcel);
        $activeSheet->setTitle('签约业绩明细表');

        //设置列标题
        $columnTitles = [
            '序号', '合同所属区域', '合同性质', '合同属性', '客户性质', '账套公司', '合同类别', '合同大类', '合同小类', '合同签署公司',
            '客户简称', '顶级客户简称', '签约客户全称', '合同编号', '签约人', '签约人所属部门', '签约日期', '录入日期', '签约金额', '签约业绩属性',
            '业绩归属时间', '签约业绩分摊金额', '结算分摊金额', '业绩归属人', '业绩归属所属部门', '业绩归属所属区域',
        ];
        $columnIndex = 'A';
        foreach ($columnTitles as $key => $value) {
            $activeSheet->setCellValue($columnIndex . '1', $value);
            $activeSheet->getColumnDimension($columnIndex)->setWidth(15);
            $activeSheet->getStyle($columnIndex . '1')->getFont()->setBold(true);
            $columnIndex++;
        }

        //批量取数
        $areaNameGroupById = $this->batchGetAreaName($data);
        $propertyNameGroupById = $this->batchGetPropertyName();
        $contractCategoryById = $this->batchGetContractCategory($data);
        $contractBigCategoryById = $this->batchGetContractBigCategory($data);
        $contractLittlerCategoryById = $this->batchGetContractLittlerCategory($data);
        $contractSignPeopleGroupById = $this->batchGetUserNameByIds($data);
        $contractSignPeopleDepartmentGroupById = $this->batchGetDepartmentByIds($data);

        //设置单元格的值
        if (!empty($data)) {
            $j = 2;
            foreach ($data as $key => $val) {
                $i = 'A';
                $activeSheet->setCellValue($i . $j, $j - 1); //序号
                $i++;
                $areaName = $this->checkKeyIsset($areaNameGroupById, $val['area_id']);
                $activeSheet->setCellValue($i . $j, $areaName === FALSE ? '' : $areaName); //合同所属区域
                $i++;
                $propertyName = $this->checkKeyIsset($propertyNameGroupById, $val['contract_property_id']);
                $activeSheet->setCellValue($i . $j, $propertyName === FALSE ? '' : $propertyName); //合同性质
                $i++;
                $attribute_name = self::getAttributeName($val['attribute_name']);
                $activeSheet->setCellValue($i . $j, $attribute_name); //合同属性
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_property'] == 0 ? '开发商' : '代理商'); //客户性质
                $i++;
                $accountCompayName = ContractAccountCompanyRepository::getContractAccountCompanyListByPropertyId($val['contract_property_id']);
                $activeSheet->setCellValue($i . $j, empty($accountCompayName) ? '' : $accountCompayName[0]->account_company_name); //账套公司
                $i++;
                $categoryName = $this->checkKeyIsset($contractCategoryById, $val['category_id']);
                $activeSheet->setCellValue($i . $j, $categoryName === FALSE ? '' : $categoryName); //合同类别
                $i++;
                $bigCategoryName = $this->checkKeyIsset($contractBigCategoryById, $val['big_category_id']);
                $activeSheet->setCellValue($i . $j, $bigCategoryName === FALSE ? '' : $bigCategoryName); //合同大类
                $i++;
                $littlerCategoryName = $this->checkKeyIsset($contractLittlerCategoryById, $val['littler_category_id']);
                $activeSheet->setCellValue($i . $j, $littlerCategoryName === FALSE ? '' : $littlerCategoryName); //合同小类
                $i++;
                $activeSheet->setCellValue($i . $j, $val['company_name']); //合同签署公司
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_name']); //客户简称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['top_customer_name']); //顶级客户简称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_full_name']); //签约客户全称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['contract_code']); //合同编号
                $i++;
                $signName = $this->checkKeyIsset($contractSignPeopleGroupById, $val['sign_people_id']);
                $activeSheet->setCellValue($i . $j, $signName); //签约人
                $i++;
                $deptName = $this->checkKeyIsset($contractSignPeopleDepartmentGroupById, $val['sign_people_department_by']);
                $activeSheet->setCellValue($i . $j, $deptName === FALSE ? '' : $deptName); //签约人所属部门
                $i++;
                $activeSheet->setCellValue($i . $j, DateTimeHelper::getDate($val['sign_date'])); //签约日期
                $i++;
                $activeSheet->setCellValue($i . $j, DateTimeHelper::getDate($val['input_date'])); //录入日期
                $i++;
                $activeSheet->setCellValue($i . $j, $val['sign_amount']); //签约金额
                $i++;
                $sa_attribute_name = self::tranContractTypeAttributeName($val['contractDistributionAmountContractType']);
                $activeSheet->setCellValue($i . $j, $sa_attribute_name); //签约业绩属性
                $i++;
                $activeSheet->setCellValue($i . $j, DateTimeHelper::getDate($val['input_date'])); // 业绩归属时间
                $i++;
                $activeSheet->setCellValue($i . $j,$val['sign_average_amount'] ? $val['sign_average_amount'] : 0); // 签约分摊金额
                $i++;
                $activeSheet->setCellValue($i . $j, $val['settlement_average_amount'] ? $val['settlement_average_amount'] : 0); // 结算分摊金额
                $i++;
                $cdaUserName = $this->checkKeyIsset($contractSignPeopleGroupById, $val['contractDistributionAmountUserId']);
                $activeSheet->setCellValue($i . $j, $cdaUserName); // 业绩归属人
                $i++;
                $cdaDepName = $this->checkKeyIsset($contractSignPeopleDepartmentGroupById, $val['contractDistributionAmountDepartmentId']);
                $activeSheet->setCellValue($i . $j, $cdaDepName); // 业绩归属部门
                $i++;
                $cdaAreaName = $this->checkKeyIsset($contractSignPeopleDepartmentGroupById, $val['contractDistributionAmountAreaId']);
                $activeSheet->setCellValue($i . $j, $cdaAreaName); // 业绩归属区域
                $j++;
            }
        }
    }

    /**
     * 是否有所属期回款业绩
     * @param type $date
     * @return boolean
     */
    private function isAchievementPeriod($date, $timeStart, $timeEnd)
    {
        $start_time = strtotime($timeStart);
        $end_time = strtotime($timeEnd);
        $time = strtotime($date);

        return $time >= $start_time && $time < $end_time ? true : false;
    }

    /**
     * 导出合同的回款业绩信息
     * @param \PHPExcel $objPHPExcel
     * @param string $status
     * @param string $property
     * @param string $keyword
     * @param string $areaId
     * @param string $signPeopleId
     */
    private function exportContractPaymentAchievementExecl($objPHPExcel, $status = null, $property = null, $keyword = null, $areaId = null, $signPeopleId = null, $timeType = 0, $timeStart = '', $timeEnd = '')
    {
        $data = ContractManageRepository::getContractPaymentAchievementListForExport($status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);

        //设置当前的sheet
        $activeSheet = self::getActiveSheet($objPHPExcel);
        $activeSheet->setTitle('回款业绩明细表');

        $columnTitles = [
            '序号', '合同所属区域', '合同性质', '合同属性', '客户性质', '账套公司', '合同类别', '合同大类', '合同小类', '合同签署公司',
            '客户简称', '顶级客户简称', '签约客户全称', '合同编号', '签约人', '签约人所属部门', '签约日期', '录入日期', '签约金额',
            '款项名称', '款项小类', '回款业绩属性', '回款业绩金额', '实收时间', '业绩归属时间', '云客业绩归属人', '云客业绩归属部门', '云客业绩归属区域',
            'ERP业绩归属人', 'ERP业绩归属ABU', 'ERP业绩归属ABU负责人', 'ERP业绩归属部门经理', 'ERP业绩归属客户经理', 'ERP业绩归属部门',
        ];
        $columnIndex = 'A';
        foreach ($columnTitles as $key => $value) {
            $activeSheet->setCellValue($columnIndex . '1', $value);
            $activeSheet->getColumnDimension($columnIndex)->setWidth(15);
            $activeSheet->getStyle($columnIndex . '1')->getFont()->setBold(true);
            $columnIndex++;
        }

        //批量取数
        $areaNameGroupById = $this->batchGetAreaName($data);
        $propertyNameGroupById = $this->batchGetPropertyName();
        $contractCategoryById = $this->batchGetContractCategory($data);
        $contractBigCategoryById = $this->batchGetContractBigCategory($data);
        $contractLittlerCategoryById = $this->batchGetContractLittlerCategory($data);
        $contractSignPeopleGroupById = $this->batchGetUserNameByIds($data);
        $contractSignPeopleDepartmentGroupById = $this->batchGetDepartmentByIds($data);

        //设置单元格的值
        if (!empty($data)) {
            $j = 2;
            foreach ($data as $key => $val) {
                $i = 'A';
                $activeSheet->setCellValue($i . $j, $j - 1); //序号
                $i++;
                $areaName = $this->checkKeyIsset($areaNameGroupById, $val['area_id']);
                $activeSheet->setCellValue($i . $j, $areaName === FALSE ? '' : $areaName); //合同所属区域
                $i++;
                $propertyName = $this->checkKeyIsset($propertyNameGroupById, $val['contract_property_id']);
                $activeSheet->setCellValue($i . $j, $propertyName === FALSE ? '' : $propertyName); //合同性质
                $i++;
                $attribute_name = self::getAttributeName($val['attribute_name']);
                $activeSheet->setCellValue($i . $j, $attribute_name); //合同属性
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_property'] == 0 ? '开发商' : '代理商'); //客户性质
                $i++;
                $accountCompayName = ContractAccountCompanyRepository::getContractAccountCompanyListByPropertyId($val['contract_property_id']);
                $activeSheet->setCellValue($i . $j, empty($accountCompayName) ? '' : $accountCompayName[0]->account_company_name); //账套公司
                $i++;
                $categoryName = $this->checkKeyIsset($contractCategoryById, $val['category_id']);
                $activeSheet->setCellValue($i . $j, $categoryName === FALSE ? '' : $categoryName); //合同类别
                $i++;
                $bigCategoryName = $this->checkKeyIsset($contractBigCategoryById, $val['big_category_id']);
                $activeSheet->setCellValue($i . $j, $bigCategoryName === FALSE ? '' : $bigCategoryName); //合同大类
                $i++;
                $littlerCategoryName = $this->checkKeyIsset($contractLittlerCategoryById, $val['littler_category_id']);
                $activeSheet->setCellValue($i . $j, $littlerCategoryName === FALSE ? '' : $littlerCategoryName); //合同小类
                $i++;
                $activeSheet->setCellValue($i . $j, $val['company_name']); //合同签署公司
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_name']); //客户简称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['top_customer_name']); //顶级客户简称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_full_name']); //签约客户全称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['contract_code']); //合同编号
                $i++;
                $signName = $this->checkKeyIsset($contractSignPeopleGroupById, $val['sign_people_id']);
                $activeSheet->setCellValue($i . $j, $signName); //签约人
                $i++;
                $deptName = $this->checkKeyIsset($contractSignPeopleDepartmentGroupById, $val['sign_people_department_by']);
                $activeSheet->setCellValue($i . $j, $deptName === FALSE ? '' : $deptName); //签约人所属部门
                $i++;
                $activeSheet->setCellValue($i . $j, DateTimeHelper::getDate($val['sign_date'])); //签约日期
                $i++;
                $activeSheet->setCellValue($i . $j, DateTimeHelper::getDate($val['input_date'])); //录入日期
                $i++;
                $activeSheet->setCellValue($i . $j, $val['sign_amount']); //签约金额
                $i++;
                $activeSheet->setCellValue($i . $j, $val['receivable_item_name']); //款项名称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['money_category_item_name']); //款项小类
                $i++;
                $pa_attribute_name = self::getAttributeName($val['pa_attribute_name']);
                $activeSheet->setCellValue($i . $j, $pa_attribute_name); //回款业绩属性
                $i++;
                $activeSheet->setCellValue($i . $j, $val['achievement_amount']); //回款业绩金额
                $i++;
                $activeSheet->setCellValue($i . $j, self::getDateTimeString($val['received_time'])); // 实收时间
                $i++;
                $activeSheet->setCellValue($i . $j, self::getDateTimeString($val['achievement_belong_time'])); // 业绩归属时间

                $j++;
            }
        }
    }

    /**
     * 导出合同的文档信息
     * @param \PHPExcel $objPHPExcel
     * @param string $status
     * @param string $property
     * @param string $keyword
     * @param string $areaId
     * @param string $signPeopleId
     */
    private function exportContractDocumentExecl($objPHPExcel, $status = null, $property = null, $keyword = null, $areaId = null, $signPeopleId = null, $timeType = 0, $timeStart = '', $timeEnd = '')
    {
        $data = ContractManageRepository::getContractDocumentListForExport($status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);

        //设置当前的sheet
        $activeSheet = self::getActiveSheet($objPHPExcel);
        $activeSheet->setTitle('纸质合同统计表');

        //设置列标题
        $columnTitles = ['客户名称', '客户简称', '合同编号', '合同所属区域', '文件类型', '纸质合同归档日期', '纸质合同存放位置', '纸质合同类型', '保管人', '所属文件夹名称'];
        $columnIndex = 'A';
        foreach ($columnTitles as $key => $value) {
            $activeSheet->setCellValue($columnIndex . '1', $value);
            $activeSheet->getColumnDimension($columnIndex)->setWidth(15);
            $activeSheet->getStyle($columnIndex . '1')->getFont()->setBold(true);
            $columnIndex++;
        }

        //设置单元格的值
        if (!empty($data)) {
            $j = 2;
            foreach ($data as $key => $val) {
                $i = 'A';
                $activeSheet->setCellValue($i . $j, $val['customer_full_name']); //客户名称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_name']); //客户简称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['contract_code']); //合同编号
                $i++;
                $activeSheet->setCellValue($i . $j, $val['area_name']); //合同所属区域
                $i++;
                $activeSheet->setCellValue($i . $j, $val['document_ext_name']);
                $i++;
                $activeSheet->setCellValue($i . $j, self::getDateTimeString($val['pigeonhole_date']));
                $i++;
                $activeSheet->setCellValue($i . $j, $val['document_path']);
                $i++;
                $activeSheet->setCellValue($i . $j, $val['contract_document_type']);
                $i++;
                $activeSheet->setCellValue($i . $j, $val['keeper_name']);
                $i++;
                $activeSheet->setCellValue($i . $j, $val['document_dir']);

                $j++;
            }
        }

    }

    /**
     * 导出违规合同信息
     * @param \PHPExcel $objPHPExcel
     * @param string $status
     * @param string $property
     * @param string $keyword
     * @param string $areaId
     * @param string $signPeopleId
     */
    private function exportContractViolatedExecl($objPHPExcel, $status = null, $property = null, $keyword = null, $areaId = null, $signPeopleId = null, $timeType = 0, $timeStart = '', $timeEnd = '')
    {
        $data = ContractManageRepository::getContractViolatedListForExport($status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);

        //设置当前的sheet
        $activeSheet = self::getActiveSheet($objPHPExcel);
        $activeSheet->setTitle('违规合同');

        //设置列标题
        $columnTitles = ['客户名称', '客户简称', '合同编号', '合同所属区域', '违规责任人', '违规大类', '违规小类', '审批人', '审批意见'];
        $columnIndex = 'A';
        foreach ($columnTitles as $key => $value) {
            $activeSheet->setCellValue($columnIndex . '1', $value);
            $activeSheet->getColumnDimension($columnIndex)->setWidth(15);
            $activeSheet->getStyle($columnIndex . '1')->getFont()->setBold(true);
            $columnIndex++;
        }

        //设置单元格的值
        if (!empty($data)) {
            $j = 2;
            foreach ($data as $key => $val) {
                $i = 'A';
                $activeSheet->setCellValue($i . $j, $val['customer_full_name']); //客户名称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_name']); //客户简称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['contract_code']); //合同编号
                $i++;
                $activeSheet->setCellValue($i . $j, $val['area_name']); //合同所属区域
                $i++;
                $activeSheet->setCellValue($i . $j, $val['principal_name']);
                $i++;
                $activeSheet->setCellValue($i . $j, $val['category_name']);
                $i++;
                $activeSheet->setCellValue($i . $j, $val['littler_category_name']);
                $i++;
                $activeSheet->setCellValue($i . $j, $val['approver_name']);
                $i++;
                $activeSheet->setCellValue($i . $j, $val['approve_comment']);

                $j++;
            }
        }

        $activeSheet->getColumnDimension('A')->setVisible(false); //把guid 设置为隐藏列
    }

    /**
     * 导出特批发票信息
     * @param \PHPExcel $objPHPExcel
     * @param string $status
     * @param string $property
     * @param string $keyword
     * @param string $areaId
     * @param string $signPeopleId
     */
    private function exportContractSpecialInvoiceExecl($objPHPExcel, $status = null, $property = null, $keyword = null, $areaId = null, $signPeopleId = null, $timeType = 0, $timeStart = '', $timeEnd = '')
    {
        $data = ContractManageRepository::getContractSpecialInvoiceListForExport($status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);

        if (isset($data) && count($data) > 0) {
            $CategoryList = [
                1 => '合同未归档',
                2 => '开票金额与合同应收金额不相等',
                3 => '开票名称与签约客户名称不一致',
                4 => '结算款未支付',
                5 => '合同未归档',
                6 => '开票名称与付款名称不一致'
            ];
            foreach ($data as $k => $v) {
                $category = $v['category'];
                $data[$k]['category_name'] = '';
                if (!is_null($category) && isset($CategoryList[$category])) {
                    $data[$k]['category_name'] = $CategoryList[$category];
                    continue;
                }
            }
        }
        //设置当前的sheet
        $activeSheet = self::getActiveSheet($objPHPExcel);
        $activeSheet->setTitle('特批发票');

        //设置列标题
        $columnTitles = ['客户名称', '客户简称', '合同编号', '合同所属区域', '合同签署公司', '开票单位', '发票抬头', '发票号码', '发票日期', '特批类型', '兑现责任人', '承诺日期', '兑现日期'];
        $columnIndex = 'A';
        foreach ($columnTitles as $key => $value) {
            $activeSheet->setCellValue($columnIndex . '1', $value);
            $activeSheet->getColumnDimension($columnIndex)->setWidth(15);
            $activeSheet->getStyle($columnIndex . '1')->getFont()->setBold(true);
            $columnIndex++;
        }

        //设置单元格的值
        if (!empty($data)) {
            $j = 2;
            foreach ($data as $key => $val) {
                $i = 'A';
                $activeSheet->setCellValue($i . $j, $val['customer_full_name']); //客户名称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['customer_name']); //客户简称
                $i++;
                $activeSheet->setCellValue($i . $j, $val['contract_code']); //合同编号
                $i++;
                $activeSheet->setCellValue($i . $j, $val['area_name']); //合同所属区域
                $i++;
                $activeSheet->setCellValue($i . $j, $val['contract_company_name']); //合同签署公司
                $i++;
                $activeSheet->setCellValue($i . $j, $val['invoice_company_name']);
                $i++;
                $activeSheet->setCellValue($i . $j, $val['invoice_customer_name']);
                $i++;
                $activeSheet->setCellValue($i . $j, $val['invoice_no']);
                $i++;
                $activeSheet->setCellValue($i . $j, self::getDateTimeString($val['invoice_date']));
                $i++;
                $activeSheet->setCellValue($i . $j, $val['category_name']);
                $i++;
                $activeSheet->setCellValue($i . $j, $val['principal_name']);
                $i++;
                $activeSheet->setCellValue($i . $j, self::getDateTimeString($val['promise_fulfil_time']));
                $i++;
                $activeSheet->setCellValue($i . $j, self::getDateTimeString($val['actual_fulfil_time']));

                $j++;
            }
        }

    }

    /**
     * 导出特批授权信息
     * @param \PHPExcel $objPHPExcel
     * @param string $status
     * @param string $property
     * @param string $keyword
     * @param string $areaId
     * @param string $signPeopleId
     */
    private function exportContractSpecialAuthorizeExecl($objPHPExcel, $status = null, $property = null, $keyword = null, $areaId = null, $signPeopleId = null, $timeType = 0, $timeStart = '', $timeEnd = '')
    {

        $data = ContractManageRepository::getContractSpecialAuthorizeListForExport($status, $property, $keyword, $areaId, $signPeopleId, $timeType, $timeStart, $timeEnd);

        if (isset($data) && count($data) > 0) {
            $CategoryList = [
                1 => '合同未归档',
                2 => '款项未回',
                3 => '合同未归档且款项未回',
                4 => '结算款未支付',
                5 => '合同扫描件未提供',
                6 => '合同扫描件未提供且结算款未支付',
            ];
            /** @var MyscrmAuthorizeRepository $authRepository */
            $authRepository = Yii::createObject(MyscrmAuthorizeRepository::className());
            /** @var MyscrmApplicationRepository $applicationRepository */
            $applicationRepository = Yii::createObject(MyscrmApplicationRepository::className());
            $applicationList = ArrayHelper::index($applicationRepository->getAllApplication(), 'ApplicationId');
            foreach ($data as $k => $v) {
                $authApplications = $authRepository->getOrganizationToAuthorizesByOrgIdAndContractId($v['organizationId'], $v['ContractId']);
                if ($authApplications === FALSE) {
                    $authApplications = [];
                }

                $appinfo = '';
                foreach ($authApplications as $key => $value) {
                    $total = $value['TotalNum'];
                    if($total <= 0){
                        continue;
                    }

                    /** @var \common\entities\common\MyscrmApplicationEntity $app */
                    $appEntity = ArrayHelper::getValue($applicationList,$value['ApplicationId']);
                    if($appEntity != null && $appEntity->UniqueName == '5021'){
                        continue;
                    }
                    $appinfo .= ($appEntity == null ? '': $appEntity->FriendlyName) . '：' . $total . ' ' . chr(13) . chr(10);
                }
                $data[$k]['appInfo'] = $appinfo;

                $category = $v['category'];
                $data[$k]['category_name'] = '';
                if (!is_null($category) && isset($CategoryList[$category])) {
                    $data[$k]['category_name'] = $CategoryList[$category];
                }
                /** @var  $contractProjectService MyscrmContractProjectService */
                $contractProjectService = Yii::createObject(MyscrmContractProjectService::className());
//                exit($v['contract_id']);
                $projecList = $contractProjectService->getProjectListByContractID($v['ContractId']);
                if (!empty($projecList)){
                    $projecList = ArrayHelper::getColumn($projecList, 'ProjName');
                    $projecList = implode(';', $projecList);
                }
                $data[$k]['projName'] = empty($projecList) ? '' : $projecList;
            }
        }
        //设置当前的sheet
        $activeSheet = self::getActiveSheet($objPHPExcel);
        $activeSheet->setTitle('特批授权');

        //设置列标题
        $columnTitles = [
            '合同甲方',
            '合同编号',
            '合同所属区域',
            '租户名称',
            '企业号',
            '租期开始日期',
            '租期结束日期',
            '开通时间',
            '应用信息',
            '项目名称',
            '特批类型',
            '兑现责任人',
            '承诺日期',
            '兑现日期'];
        $columnIndex = 'A';
        foreach ($columnTitles as $key => $value) {
            $activeSheet->setCellValue($columnIndex . '1', $value);
            $activeSheet->getColumnDimension($columnIndex)->setWidth(15);
            $activeSheet->getStyle($columnIndex . '1')->getFont()->setBold(true);
            $columnIndex++;
        }

        //设置单元格的值
        if (!empty($data)) {
            $j = 2;
            foreach ($data as $key => $val) {
                if (empty($val['appInfo'])) {
                    continue;   //如果应用信息为空，则不作导出 
                }
                $i = 'A';
                $activeSheet->setCellValue($i . $j, $val['customer_name']); //合同甲方
                $i++;
                $activeSheet->setCellValue($i . $j, $val['contract_code']); //合同编号
                $i++;
                $activeSheet->setCellValue($i . $j, $val['area_name']); //合同所属区域
                $i++;
                $activeSheet->setCellValue($i . $j, $val['FriendlyName']);
                $i++;
                $activeSheet->setCellValue($i . $j, $val['UniqueName']);
                $i++;
                $activeSheet->setCellValue($i . $j, self::getDateTimeString($val['BeginOn']));
                $i++;
                $activeSheet->setCellValue($i . $j, self::getDateTimeString($val['EndOn']));
                $i++;
                $activeSheet->setCellValue($i . $j, self::getDateTimeString($val['EstablishTime']));
                $i++;
                $activeSheet->setCellValue($i . $j, $val['appInfo']);   //应用信息
                $i++;
                $activeSheet->setCellValue($i . $j, $val['projName']);
                $i++;
                $activeSheet->setCellValue($i . $j, $val['category_name']);
                $i++;
                $activeSheet->setCellValue($i . $j, $val['principal_name']);
                $i++;
                $activeSheet->setCellValue($i . $j, self::getDateTimeString($val['promiseFulfilTime']));
                $i++;
                $activeSheet->setCellValue($i . $j, self::getDateTimeString($val['actualFulfilTime']));

                $j++;
            }
        }

    }

    private static function getDateTimeString($value, $format = null)
    {
        if (empty($format)) {
            $format = "Y-m-d";
        }
        if (is_null($value) || empty($value)) {
            return '';
        }

        return date($format, strtotime($value));
    }

    /**
     * @param $userId 收件人id
     * @param $subject 邮件主题
     * @param $template 模板名称：invoiceExpired、invoiceNoContract、receivableExpired、revenue、verify
     * @param $params 模板对应的字段内容
     */
    private function sendEmail($userId, $subject, $template, $params, $cc)
    {
        $user = ErpUserRepository::getUserById($userId);
        if (empty($user)) {
            return;
        }
        //获取抄送人
        $copyToEMail = ContractEmailContactsRepository::getCCContactsByBu($user['BUGUID'], $user['UserCode']);

        $params['ScrmUrl'] = \Yii::$app->params['ScrmUrl'];
        $params['userName'] = $user['UserName'];

        if (is_array($cc)) {
            $copyToEMail = array_merge($copyToEMail, $cc);
        }

        return $this->sendMailHandler([$user['Email'] => $user['UserName']], $subject, $template, $params, $copyToEMail);
    }

    /**
     * @param $userId 收件人id
     * @param $subject 邮件主题
     * @param $template 模板名称：invoiceExpired、invoiceNoContract、receivableExpired、revenue、verify
     * @param $params 模板对应的字段内容
     */
    private function sendEmailForAuthorizeExpired($userId, $subject, $template, $params, $cc)
    {
        $user = ErpUserRepository::getUserById($userId);
        if (empty($user)) {
            return;
        }
        //获取抄送人
        $copyToEMail = ContractEmailContactsRepository::getCCContactsByBu($user['BUGUID'], $user['UserCode']);

        $toEmail = $copyToEMail;
        $params['msg'] = '';
        $hasCc = true;
        //如果没有配置抄送人，则提醒
        if (empty($copyToEMail)) {
            $params['userName'] = '付小玲';
            $toEmail = $cc;
            $params['msg'] = '该公司未设置租期到期提醒责任人，请确认';
            $hasCc = false;
        }

        $params['ScrmUrl'] = \Yii::$app->params['ScrmUrl'];

        if ($hasCc && is_array($cc)) {
            $copyToEMail = array_merge($copyToEMail, $cc);
        }

        if(YII_ENV_PROD){
            return $this->sendMailHandler($toEmail, $subject, $template, $params, $copyToEMail);
        }
        return true;
    }

    private function sendMailHandler($sendToUser, $subject, $template, $params, $cc)
    {
        $params['ScrmUrl'] = \Yii::$app->params['ScrmUrl'];
        return EmailService::sendEMail($sendToUser, $subject, 'contract/' . $template, $params, $cc);
    }

    /**
     * 根据时间获取合同
     * @param $beginTime
     * @param $endTime
     * @return array|\common\repositories\myhtsq\type
     */
    public function getContractListByTime($beginTime, $endTime, $contractGuid)
    {
        $data = ContractManageRepository::getContractListByTime($beginTime, $endTime, $contractGuid);
        $data = $this->_setContractRent($data);
        return $data;
    }

    /**
     * 获取合同返款列表
     */
    public function getContractFkList($contractGuid)
    {
        return ContractManageRepository::getContractFkList($contractGuid);
    }

    private function _setContractBillPaymentAmount($contract_list)
    {
        $result = [];
        foreach ($contract_list as $contract) {
            $contract_id = $contract['contract_id'];
            $billingAmount = $paymentAmount = 0;
            if (!empty($contract_id)) {
                $receivables = $this->getReceivableInfoByContractId($contract_id);
                if (isset($receivables) && count($receivables) > 0) {
                    foreach ($receivables as $k => $v) {
                        $billingAmount += floatval($v['billing_amount']);
                        $paymentAmount += floatval($v['received_amount']);
                    }
                }
            }

            $contract['BillAmount'] = $billingAmount;
            $contract['PaymentAmount'] = $paymentAmount;
            $result[] = $contract;
        }

        return $result;
    }

    private function _setContractRent($contract_list)
    {
        $result = [];
        foreach ($contract_list as $contract) {
            $contract_id = isset($contract['contract_id']) ? $contract['contract_id'] : $contract['ContractGUID'];
            if (!empty($contract_id)) {
                $contractInfo = MyscrmContractRepository::getContractByContractNum($contract['ContractCode']); //获取合同表信息

                $revenueInfo = [];
                if(isset($contract['revenue_id'])) {
                    $revenueInfo = ContractRevenueRepository::getContractRevenueInfoByRevenueId($contract['revenue_id']);
                }


                //获取租期信息
                if (empty($contractInfo)) {
                    $contract['RentBeginDate'] = '';
                    $contract['RentEndDate'] = '';
                    $contract['EstablishTime'] = '';
                    $contract['BeginOn'] = '';
                    $contract['EndOn'] = '';
                } else {
                    $contract['RentBeginDate'] = $contractInfo->BeginOn;
                    $contract['RentEndDate'] = $contractInfo->EndOn;
                    $contract['EstablishTime'] = empty($revenueInfo['establish_time'])?$contractInfo->PerformanceAccountingTime:$revenueInfo['establish_time'];
                    $contract['BeginOn'] = empty($revenueInfo['begin_on'])?$contractInfo->BeginOn:$revenueInfo['begin_on'];
                    $contract['EndOn'] =  empty($revenueInfo['end_on'])?$contractInfo->EndOn:$revenueInfo['end_on'];
                }
            }
            $result[] = $contract;
        }

        return $result;
    }

    /**
     * 根据时间获取合同
     * @param $beginTime
     * @param $endTime
     * @return array
     */
    public function getContractListByTimeNoAsFields($beginTime, $endTime)
    {
        $data = ContractManageRepository::getContractListByTimeNoAsFields($beginTime, $endTime);
        $data = $this->_setContractRent($data);
        return $data;
    }

    /**
     * 签约业绩接口
     * @param type $beginTime
     * @param type $endTime
     */
    public function getSignAchievementsByTime($beginTime, $endTime)
    {
        return ContractManageRepository::getSignAchievementsByTime($beginTime, $endTime);
    }

    /**
     * 回款信息接口
     * @param type $beginTime
     * @param type $endTime
     */
    public function getPaymentInfoByTime($beginTime, $endTime, $contractGuid)
    {
        return ContractManageRepository::getPaymentInfoByTime($beginTime, $endTime, $contractGuid);
    }

    /**
     * 款项发票回款关联表
     * @param type $beginTime
     * @param type $endTime
     */
    public function getInvoicePaymentByTime($beginTime, $endTime, $contractGuid)
    {
        return ContractManageRepository::getInvoicePaymentByTime($beginTime, $endTime, $contractGuid);
    }

    /**
     * 回款与发票及应收款对应关系
     * @param $payment_id
     * @param $delpayment
     * @return bool
     */
    public function getInvoicePaymentByPaymentId($payment_id,$delpayment=null)
    {
        return ContractManageRepository::getInvoicePaymentByPaymentId($payment_id,$delpayment);
    }


    /**
     * 应收款表
     * @param type   $beginTime
     * @param type   $endTime
     * @param string $contractId
     */
    public function getReceivableInfoByTime($beginTime, $endTime, $contractId = '')
    {
        return ContractManageRepository::getReceivableInfoByTime($beginTime, $endTime, $contractId);
    }

    /**
     * 获取所有的发票摘要信息
     * @return array
     */
    public function getInvoiceAllSummary()
    {
        return InvoiceSummaryRepository::getInvoiceAllSummary();
    }


    /**
     * 发票信息接口
     * @param type $beginTime
     * @param type $endTime
     */
    public function getInvoicesByTime($beginTime, $endTime, $contractGuid)
    {
        $invoicesInfo = ContractManageRepository::getInvoicesByTime($beginTime, $endTime, $contractGuid);

        foreach ($invoicesInfo as $index => &$item) {
            $flag = 0; //正常发票
            if (!empty($item['red_by_invoice_id'])) {
                $flag = 1; //被红冲的发票
            }
            if ($item['is_red_invoice'] == 1) {
                $flag = 2; //红冲的发票
            }
            if ($item['is_receipt'] == 1) {
                $flag = 3; //收据
            }
            unset($item['red_by_invoice_id']);
            unset($item['is_red_invoice']);
            unset($item['is_receipt']);
            $item['ReceiptAttribute'] = $flag;

            if($item['FpLx'] == 0) {
                $invoicesInfo[$index]['FpLx'] = '增值税普通发票';
            }
            if($item['FpLx'] == 1) {
                $invoicesInfo[$index]['FpLx'] = '增值税专用发票';
            }

            $invoicesInfo[$index]['YcType'] = $this->resetYcType($item['YcType']);

            if(! empty($item['ContractGuid'])) {
                $invoicesInfo[$index]['IsRelaToContract'] = 1;
            } else {
                $invoicesInfo[$index]['IsRelaToContract'] = 0;
            }

            if(! empty($item['YcJhDate']) && ! empty($item['YcSjDate'])) {
                $invoicesInfo[$index]['IsYcFp'] = 1;
            } else {
                $invoicesInfo[$index]['IsYcFp'] = 0;
            }
        }

        return $invoicesInfo;
    }

    /**
     * 租户信息接口
     * @param $beginTime
     * @param $endTime
     * @return array
     */
    public function getGetOrganizationInfoByTime($beginTime, $endTime, $contractGuid)
    {
        $contractArr = MyscrmContractRepository::getContractOrganizationInfo($beginTime, $endTime);

        /** @var MyscrmContractManageService $contractManageService */
        $contractManageService = Yii::createObject(MyscrmContractManageService::className());

        $ret = [];
        if (!empty($contractArr)){
            foreach ($contractArr as &$contractInfo){
                $contractCode = $contractInfo['DeliveryCode'];

                $manageInfo = $contractManageService->getContractManageByCode($contractCode);

                if (empty($manageInfo)){
                    continue;
                }

                if ($manageInfo->is_cancelled == 0 && $manageInfo->contract_status > 0){
                    $contractInfo['ContractGUID'] = $manageInfo->contract_id;

                    if(! empty($contractGuid)) {
                        if($contractGuid == $manageInfo->contract_id) {
                            $ret[] = $contractInfo;
                        }
                    } else {
                        $ret[] = $contractInfo;
                    }
                }
            }
        }

        return $ret;
    }

    /**
     * 产品信息接口
     * @param $beginTime
     * @param $endTime
     * @param $contractGuid
     * @return array
     */
    public function getProductInfoByTime($beginTime, $endTime, $contractGuid) {
        $data = ContractManageRepository::getProductInfoByTime($beginTime, $endTime, $contractGuid);
        foreach ($data as &$datum) {
            $datum['Rent_Time'] = (int)$datum['Rent_Time'];
        }
        return $data;
    }

    public function getRevenueInfoByTime($beginTime, $endTime)
    {
        $data = ContractRevenueRepository::getRevenueInfoByTime($beginTime, $endTime);
        $data = $this->_setContractBillPaymentAmount($data);
        $data = $this->_setContractRent($data);
        return $data;
    }

    public function getRevenueInfoByRecognitionTime($recognition)
    {
        $data = ContractRevenueRepository::getRevenueInfoByRecognitionTime($recognition);
        $data = $this->_setContractBillPaymentAmount($data);
        $data = $this->_setContractRent($data);
        return $data;
    }

    private function getUserNameById($userGUID, $default = '')
    {
        if (empty($userGUID)) {
            return $default;
        }

        $name = ErpUserRepository::getUserNameByBuguid($userGUID);
        return empty($name) ? $default : $name;
    }

    private function getBuNameById($buGUID, $default = '')
    {
        if (empty($buGUID)) {
            return $default;
        }

        $name = ErpBusinessUnitRepository::getBunameByBuguid($buGUID);
        return empty($name) ? $default : $name;
    }

    /**
     * 获取业绩信息
     * @param string $contractId 合同id
     * @return array 返回业绩信息数组数据
     */
    public function getSignDely($contractId)
    {

        $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); // 获取model
        if (empty($contractModel)) { // 合同不存在
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_EXISTS);
        }

        //列表信息
        $signDely = SignDelyRepository::getSignDelyListByContractId($contractId);
        $r_data['sign_dely'] = $signDely;
        foreach ($signDely as $key => $val) {
            $r_data['sign_dely'][$key]['belong_name'] = $this->getUserNameById($val['belong_by']); //获取归属人名称
            $r_data['sign_dely'][$key]['department_name'] = $this->getBuNameById($val['department_by']); //获取部门名称
            $r_data['sign_dely'][$key]['area_name'] = $this->getBuNameById($val['area_by']); //获取区域名称
        }

        //附件信息
        $r_data['attachement'] = SignDelyAttachementRepository::getAttachementListByContractId($contractId);

        //交付业绩总额
        $r_data['payment_amount'] = ContractPaymentRepository::getPaymentSumByContractId($contractId);

        return $r_data;
    }

    /**
     * 保存合同文档信息
     * @param string $contractId 合同id
     * @param array $files 文件数组
     * @param array $signDelys 交付信息数组
     * @return boolean
     */
    public function saveSignDely($contractId, $files, $signDelys)
    {
        $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); // 获取model
        if (empty($contractModel)) { // 合同不存在
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_EXISTS);
        }

        //处理保存文件
        if (!empty($files) && is_array($files)) {

            foreach ($files as $value) {
                if (!isset($value ['__type'])) {
                    $value ['__type'] = 'update';
                }
                switch ($value ['__type']) {
                    case 'delete' :
                        SignDelyAttachementRepository::delAttachementById($value['attachement_id']);
                        break;
                    case 'add' :
                        $signDelyAttachement = new SignDelyAttachementEntity();
                        $signDelyAttachement->setAttributes($value);
                        $explode = explode('.', $value['attachement_name']);
                        $extName = end($explode);
                        $signDelyAttachement->attachement_ext_name = $extName;
                        $signDelyAttachement->contract_id = $contractId;
                        if ($signDelyAttachement->validate()) {
                            SignDelyAttachementRepository::addAttachement($signDelyAttachement);
                        }
                        break;
                }
            }
        }

        // 处理保存业绩交付信息
        if (!empty($signDelys) && is_array($signDelys)) {
            foreach ($signDelys as $value) {
                if (!isset($value ['__type'])) {
                    $value ['__type'] = 'update';
                }
                switch ($value ['__type']) {
                    case 'delete' :
                        SignDelyRepository::deleteSignDelyByDelyId($value['dely_id']);
                        break;
                    case 'add' :
                        $signDelyEntity = new SignDelyEntity();
                        $signDelyEntity->load($value, '');
                        $signDelyEntity->dely_id = StringHelper::uuid();
                        $signDelyEntity->contract_id = $contractId;
                        $signDelyEntity->attribute_name = $contractModel->attribute_name;
                        if ($signDelyEntity->validate()) {
                            SignDelyRepository::addSignDely($signDelyEntity); // 新增合同文档信息
                        }
                        break;
                    case '' :
                    case 'update' :
                        $signDelyEntity = new SignDelyEntity ();
                        $signDelyEntity->load($value, '');
                        if ($signDelyEntity->validate()) {
                            SignDelyRepository::updateSignDely($signDelyEntity); // 新增合同文档信息
                        }
                        break;
                }
            }
        }
        return true;
    }

    /**
     * 根据款项名称,获取款项id
     * @param string $receivableItemName 款项名称
     * @return string 款项名称
     */
    public function getReceivableItemIdByItemName($receivableItemName)
    {
        return ReceivableItemRepository::getReceivableItemIdByItemName($receivableItemName);
    }

    /**
     * 根据款项id,获取款项名称
     * @param string $receivableItemName 款项名称
     * @return string 款项名称
     */
    public function getReceivableItemNameByItemId($receivableItemName)
    {
        return ReceivableItemRepository::getReceivableItemNameByItemId($receivableItemName);
    }

    /**
     * 根据id,获取名称
     * @param string $moneyCategoryItemName 名称
     * @return string 名称
     */
    public function getMoneyCategoryItemIdByItemName($moneyCategoryItemName)
    {
        return MoneyCategoryItemRepository::getMoneyCategoryItemIdByItemName($moneyCategoryItemName);
    }

    /**
     * 处理从商机系统传过来的数据，更新合同、应收款、收入、文档
     *
     * @param $contract
     * @param array $productData
     * @param array $documentData
     */
    public function doUpdateFromBusinessSystem($contract, $productData = [], $documentData = [])
    {
        $logParams = [
            'contract'    => $contract,
            'product'     => $productData,
            'document'    => $documentData,
        ];
        Yii::info('商机系统更新合同接口传值：' . json_encode($logParams),'channel');

        //保存合同，开启事务
        $connection = ContractEntity::getDb();
        $transaction = $connection->beginTransaction();

        try{
            $contractResult = $this->updateContract($contract, $productData, []);
            if (! $contractResult) {
                $transaction->rollBack();
                return $this->setAndReturn(__LINE__, '更新合同失败');
            } else {
                $this->calcApplicationAmount($contract['contract_id'], true);

                $documentResult = $this->saveContractDocuments($contract['contract_id'], $documentData, []);
                if($documentResult === false){
                    $transaction->rollBack();
                    return $this->setAndReturn(__LINE__, '更新文档信息失败');
                }
            }
        } catch (\Exception $ex){
            $transaction->rollBack();
            Yii::error('商机系统更新合同接口保存失败：' . (string)$ex);
            return $this->setAndReturn(__LINE__, '更新合同失败');
        }

        $transaction->commit();
        return true;
    }

    /**
     * 处理从商机系统传过来的数据，插入合同、应收款、收入、文档
     * @param $contract
     * @param $receivableData
     * @return bool
     * @throws \yii\base\InvalidConfigException
     * @throws \yii\db\Exception
     */
    public function doInsertFromBusinessSystem($contract, $receivableData, $productData = [], $revenueData = [], $documentData = [])
    {
        $logParams = [
            'contract'    => $contract,
            'receivable'  => $receivableData,
            'product'     => $productData,
            'revenue'     => $revenueData,
            'document'    => $documentData,
        ];
        Yii::info('商机系统添加合同接口传值：' . json_encode($logParams));

        /** @var ContractReceivableService $contractReceivableService */
        $contractReceivableService = Yii::createObject(ContractReceivableService::className());

        //保存合同，开启事务
        $connection = ContractEntity::getDb();
        $transaction = $connection->beginTransaction();
        try {
            $result = $this->addContract($contract, $productData, [], true);
            if (!$result) {
                $transaction->rollBack();
                return $this->setAndReturn(__LINE__, '添加合同失败: '.self::getErrMsg());
            }

            foreach ($receivableData as $receivable) {
                $receivableArr = [];
                $receivableArr['contract_id'] = $receivable['contract_id']; //合同ID
                $receivableArr['receivable_id'] = $receivable['receivable_id']; //应收款GUID

                //传过来的是文字，需要转换为ID
                $receivable_item_name = $receivable['receivable_item_name']; //款项名称
                $money_category_item_name = $receivable['money_category_item_name']; //款项小类
                $receivableArr['receivable_item_id'] = $this->getReceivableItemIdByItemName($receivable_item_name); //云客租用款  '882-fd02-11e4-bed8-00155d02c832'
                $receivableArr['money_category_item_id'] = $this->getMoneyCategoryItemIdByItemName($money_category_item_name);

                if ($receivableArr['receivable_item_id'] == '') {
                    $transaction->rollBack();
                    return $this->setAndReturn(__LINE__, '系统不存在此款项名称');
                }
                if ($receivableArr['money_category_item_id'] == '') {
                    $transaction->rollBack();
                    return $this->setAndReturn(__LINE__, '系统不存在此款项小类名称');
                }

                $receivableArr['payment_condition'] = $receivable['payment_condition']; //付款条件
                $receivableArr['receivable_amount'] = $receivable['receivable_amount']; //应收金额
                $receivableArr['receivable_date'] = $receivable['receivable_date']; //应收日期

                /* 收入项 新增字段 */
                $receivableArr['revenue_type'] = '7f94a49d-fcf6-11e4-bed8-00155d02c832'; //由于商机系统那边没有此字段，故默认为“租用服务收入项”
                if(isset($receivable['income_type']) && ! empty($receivable['income_type'])){
                    $revenueTypeId = BussAccountTypesRepository::getRevenueTypeIdByName(trim($receivable['income_type']));
                    if($revenueTypeId != false){
                        $receivableArr['revenue_type'] = $revenueTypeId;
                    }
                }

                /* 备注 新增字段 */
                $receivableArr['remark'] = '';
                if(isset($receivable['remark']) && ! empty($receivable['remark'])){
                    $receivableArr['remark'] = $receivable['remark'];
                }

                if ($receivable['receivable_type'] == '新签') {
                    $receivableArr['receivable_type'] = '1';
                } else {
                    $receivableArr['receivable_type'] = '2';
                }

                $receivableArr['payee_id']       = $receivable['unite_sales_id'];
                $receivableArr['unite_sales_id'] = $receivable['unite_sales_id']; //售前人员

                $contractReceivableModel = new ContractReceivableModel(['scenario' => 'savecontractreceivable']);
                if ($contractReceivableModel->load($receivableArr, '')) {
                    $result = $contractReceivableService->saveContractReceivable($contractReceivableModel, true);
                    if ($result === false) {
                        $transaction->rollBack();
                        return $this->setAndReturn(__LINE__, '添加应收款失败');
                    }
                } else {
                    $transaction->rollBack();
                    return $this->setAndReturn(__LINE__, '添加应收款时参数有误');
                }
            }

            //收入信息
            if(! empty($revenueData)){
                if($revenueData[0]['account_company_id'] == 0){
                    return $this->setAndReturn(__LINE__, '不存在该合同签署公司');
                }

                $revenueResult = $this->submitRevenue($contract['contract_id'], $revenueData[0]['account_company_id'], $revenueData);
                if($revenueResult === false){
                    $transaction->rollBack();
                    return $this->setAndReturn(__LINE__, '添加收入失败');
                }
            }

            //文档信息
            if(! empty($documentData)){
                $documentResult = $this->saveContractDocuments($contract['contract_id'], $documentData, []);
                if($documentResult === false){
                    $transaction->rollBack();
                    return $this->setAndReturn(__LINE__, '添加文档信息失败');
                }
            }

            $transaction->commit();
            return true;

        } catch (\Exception $ex) {
            $transaction->rollBack();
            Yii::error('商机系统添加草稿合同接口保存失败：' . (string)$ex);
            return $this->setAndReturn(__LINE__, '生成合同失败');
        }

    }


    /**
     * 根据合同ID获取对应的应收款项明细
     * @param string $contractId 合同id
     * @param boolean $withBadDebt 是否包含坏账
     * @return array
     */
    public function getReceivableInfoByContractId($contractId, $withBadDebt = true)
    {
        return ContractReceivableRepository::getReceivableInfoByContractId($contractId, $withBadDebt);
    }

    public function getAllContractApplicationByContractId($contractId)
    {
        return ContractApplicationRepository::getAllContractApplicationByContractId($contractId);
    }

    /**
     * 删除合同[草稿,作废]
     * @param $contractId 合同表 contract_mange 的id
     */
    public function deleteContract($contractId)
    {
        $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); //获取model
        //合同不存在
        if (empty($contractModel)) {
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_EXISTS);
        }

        //状态判断
        if ($contractModel->contract_status != ContractManageEntity::APPROVE_STATUS_DRAFT && $contractModel->is_cancelled != ContractManageEntity::CONTRACT_IS_CANCELLED) {
            return $this->setAndReturn(-1, "该合同不允许删除");
        }

        //发票中已经有数据
        if (InvoiceService::checkInvoiceExists($contractId)) {
            return $this->setAndReturn(-1, "发票中已有合同数据,不允许删除");
        }

        $db = ContractEntity::getDb();
        $transaction = $db->beginTransaction();
        try {
            //myscrm_contract_manage 合同
            ContractManageRepository::deleteByContractId($contractId);

            //myscrm_contract_application   合同产品
            ContractApplicationRepository::deleteByContractId($contractId);

            //myscrm_sign_achievement   签约数据
            SignAchievementRepository::deleteByContractId($contractId);

            //myscrm_contract_principal 合同负责人
            ContractPrincipalRepository::deleteByContractId($contractId);

            //myscrm_contract_revenue 收入信息
            ContractRevenueRepository::deleteByContractId($contractId);

            //myscrm_contract_receivable 应收信息
            ContractReceivableRepository::deleteByContractId($contractId);

            //myscrm_contract_balance_attachement 附件信息
            ContractBalanceAttachementRepository::deleteByContractId($contractId);

            //myscrm_document 文档仓库 business_id 对应 contractId
            DocumentRepository::delDocumentByBusinessId($contractId);

            //myscrm_payment_achievement 回款信息
            PaymentAchievementRepository::deleteByContractId($contractId);

            $transaction->commit();
        } catch (\Exception $e) {
            $transaction->rollBack();
            \Yii::error((string)$e);
            return $this->setAndReturn(__LINE__, '删除失败');
        }
        return true;
    }

    /**
     * 计算合同的签约、结算、回款分摊金额
     * @param $contractId
     * @return bool
     */
    public function calculateDistributionAmount($contractId)
    {
        //2016年之前的合同不处理
        $contractEntity = ContractManageRepository::getContractManageModelByContractId($contractId);
        $year = date('Y', strtotime($contractEntity->input_date));
        if ($year < '2017'){
            return true;
        }

        //判断有没有分摊金额,没则新增,有则修改
        $hasDistributionAmount = ContractManageRepository::checkHasDistributionByContractId($contractId);
        $trans = ContractEntity::getDb()->beginTransaction();
        try {

            if ($hasDistributionAmount) {
                //修改
                $updateResult = $this->maintainDistributionAmount($contractId);
                if ($updateResult === false) {
                    $trans->rollBack();
                    return $this->setAndReturn(__LINE__, $this->getErrMsg());
                }
            } else {
                //新增
                $addResult = $this->addDistributionAmount($contractId);
                if ($addResult === false) {
                    $trans->rollBack();
                    return $this->setAndReturn(__LINE__, $this->getErrMsg());
                }
            }

            $calculatePaymentResult = $this->calculatePayment($contractId);
            if ($calculatePaymentResult === false) {
                $trans->rollBack();
                return $this->setAndReturn(__LINE__, $this->getErrMsg());
            }

            $trans->commit();
        } catch (\Exception $e) {
            $trans->rollBack();
            \Yii::error($e->getMessage());
            return false;
        }

        return true;
    }

    /**
     * 当表中没有该合同信息时,插入数据
     * @param $contractId
     * @return bool|int
     */
    private function addDistributionAmount($contractId)
    {
        $selectSql = "SELECT 
  IF(SUM(c2a.sign_average_amount),SUM(c2a.sign_average_amount),0) AS sign_average_amount,
  IF(SUM(c2a.settlement_average_amount),SUM(c2a.settlement_average_amount),0) AS settlement_average_amount,
  c2a.`contract_type` AS contract_type,
  c2a.`contract_id` AS contract_id,
  cm.`sign_people_id` AS user_id,
  cm.`area_id` AS area_id,
  cm.`sign_people_department_by` AS department_id,
  cm.`input_date` AS input_date,
  mai.`is_saas` AS is_saas
FROM
  `myscrm_contract_application` c2a 
  LEFT JOIN `myscrm_contract_manage` cm 
    ON c2a.`contract_id` = cm.`contract_id` 
  LEFT JOIN `myscrm_application_info` mai 
    ON mai.`application_id`= c2a.`application_id`
  WHERE c2a.`contract_type` IS NOT NULL AND c2a.`contract_id`=:contractId
GROUP BY c2a.`contract_type`,
  c2a.`contract_id`,
  mai.`is_saas` ;";

        try {
            $toDoData = ContractApplicationEntity::getDb()->createCommand($selectSql, [':contractId' => $contractId])->queryAll();
            if (empty($toDoData)){
                return true;
            }

            foreach ($toDoData as $item){
                $contractInfo = [
                    'sign_people_id' => $item['user_id'],
                    'area_id' => $item['area_id'],
                    'sign_people_department_by' => $item['department_id'],
                    'contract_id' => $item['contract_id'],
                    'input_date' => $item['input_date'],
                ];

                $addResult = $this->addDistributionByContractType(
                    $contractInfo,
                    $item['contract_type'],
                    $item['is_saas'],
                    $item['sign_average_amount'],
                    $item['settlement_average_amount']
                );
                if($addResult === false){
                    return self::setAndReturn(__LINE__, self::getErrMsg());
                }
            }
        } catch (\Exception $e) {
            Yii::error($e->getMessage());
            return false;
        }

        return true;
    }

    /**
     * 维护回款数据
     * 按比例分摊回款金额
     * @param $contractId
     * @return bool
     */
    public function calculatePayment($contractId)
    {
        //合同全部的回款数据
        /** @var InvoicePaymentRepository $paymentRepository */
        $paymentRepository = Yii::createObject(InvoicePaymentRepository::className());
        $sumPaymentAmount = $paymentRepository->getSumPaymentByContractId($contractId);

        // 没有回款数据的话不处理,直接返回true
        if (!$sumPaymentAmount) {
            return true;
        }

        $distributionList = ContractManageRepository::getDistributionByContractId($contractId);
        if (empty($distributionList)) {
            return true;
        }

        $distributionSignAmountArr = ArrayHelper::getColumn($distributionList, 'sign_average_amount');
        $sumDistributionSignAmount = array_sum($distributionSignAmountArr);
        if ($sumDistributionSignAmount == 0){
            return true;
        }

        foreach ($distributionList as $distribution) {
            $signAmount = $distribution['sign_average_amount'];
            $amountId = $distribution['amount_id'];

            $updateAmount = ($signAmount * $sumPaymentAmount) / $sumDistributionSignAmount;

            $updateResult = ContractManageRepository::updateDistribution($amountId, $updateAmount);
            if ($updateResult === false) {
                return $this->setAndReturn(__LINE__, '维护回款分摊金额失败');
            }
        }

        return true;
    }


    /**
     * 租户管理授权推送授权信息接口
     * TODO 1.考虑校验规则; 2.事物回滚
     */
    public function authorizationPush($arr,$item)
    {

        //TODO  需要将合同编号转合同id
        $contractManage = new ContractManageRepository();
        $contractManage = $contractManage->getContractManageArrByCode($arr['contract_num']);
        $arr['contract_id'] = $contractManage['contract_id'];

        if(!empty($arr['is_from_tenant'])&&$arr['is_from_tenant'] == 1){//租户过来的产品需要将合同编号转id

            //格式化租期
            $rent_period = (strtotime($arr['end_on'])-strtotime($arr['begin_on']))/3600/24/30;
            $rent_period = $this->formatLease($rent_period);
            $arr['rent_period'] = $rent_period;
            $arr['product_type'] = $arr['contract_type'];

        }

        //TODO 记得完善事务
        // 开启事务
        $configDataBase = ContractEntity::getDb();
        $trans = $configDataBase->beginTransaction();
        try{

            $resultAdd = $this->addAuthorizeByOrganizationId($arr);//租户管理中的开通产品
            $this->putLog('addAuthorizeByOrganizationId=>'.$resultAdd,__METHOD__,$resultAdd);

            if($resultAdd === false){
                $trans->rollBack();
                return self::setAndReturn(__LINE__, self::getErrMsg() ? self::getErrMsg() : '产品写入授权失败');
            }

            $ykPropertyId = [
                ContractPropertyEntity::MYYK_PROPERTY_JOINT_SIGNED_SETTLEMENT_OPERATION_ID,//明源签约-直属
                ContractPropertyEntity::MY_PROPERTY_DIRECTLY_OPERATION_ID,//明源签约-联营
                ContractPropertyEntity::MY_PROPERTY_JOINT_OPERATION_ID,//联营签约-云客结算
            ];

            //获取合同性质
            $contractPropertyId = $this->getContractNature($arr['contract_id']);

            //TODO 依据如果是非云客类合同则产生收入应收

            if(in_array($contractPropertyId,$ykPropertyId)) {//将产品信息写入业绩表

                $SummaryArr = $this->getContractOrderSummaryById($arr['contract_id'],$toReceivable = true);

                $this->putLog('$SummaryArr=>'.var_export($SummaryArr,true),__METHOD__,$SummaryArr);

                if($SummaryArr['status'] === false){
                    $trans->rollBack();
                    return self::setAndReturn(__LINE__,$SummaryArr['msg']);
                }

                //TODO 通过信息增加到  应收款里面
                $model = new ContractReceivableService;
                $resultAdd = $model->saveContractReceivableByEstablish($SummaryArr,$arr['contract_id']);

                $this->putLog('saveContractReceivableByEstablish=>'.$resultAdd,__METHOD__,$resultAdd);

                if($resultAdd === false){
                    $trans->rollBack();
                    return self::setAndReturn(__LINE__,'应收款写入失败');
                }
            }
            $trans->commit();
            $data  = true;

        }catch(\Exception $e){
            $trans->rollBack();
            return self::setAndReturn(__LINE__,'开通,收入,应收出现异常');
        }

        return $data;
    }

    public function handleRevenueByRedFlush($contract_num){

        $contractManage = new ContractManageRepository();
        $contractManage = $contractManage->getContractManageArrByCode($contract_num);
        $contract_id = $contractManage['contract_id'];
        $contractPropertyId = $contractManage['contract_property_id'];
        $ykPropertyId = [
            ContractPropertyEntity::MYYK_PROPERTY_JOINT_SIGNED_SETTLEMENT_OPERATION_ID,//明源签约-直属
            ContractPropertyEntity::MY_PROPERTY_DIRECTLY_OPERATION_ID,//明源签约-联营
            ContractPropertyEntity::MY_PROPERTY_JOINT_OPERATION_ID,//联营签约-云客结算
        ];

        $ykPropertyClassId = [
            ContractPropertyEntity::MYYK_PROPERTY_DIRECTLY_UNDER_ID,//云客签约-直属
            ContractPropertyEntity::MYYK_PROPERTY_JOINT_OPERATION_ID,//云客签约-直属区域
            ContractPropertyEntity::MYYK_PROPERTY_DIRECT_SALES_ID,//云客直销
        ];

        //TODO 依据如果是非云客类合同则产生收入应收
        if(in_array($contractPropertyId,$ykPropertyId)) {//将产品信息写入业绩表
            //TODO 通过信息增加到  收入里面        三个条件进行分组
            $SummaryArrForLease = $this->getContractOrderSummaryByDateAndLeaseById($contract_id,$toReceivable = true);
            $this->putLog('$SummaryArrForLease=>'.json_encode($SummaryArrForLease,true),__METHOD__,$SummaryArrForLease);

            if($SummaryArrForLease['status'] === false){
                return self::setAndReturn(__LINE__,$SummaryArrForLease['msg']);
            }
            $resultAdd = $this->submitRevenueByEstablish($SummaryArrForLease,$contract_id);

            $this->putLog('submitRevenueByEstablish=>'.$resultAdd,__METHOD__,$resultAdd);

            if($resultAdd === false){
                return self::setAndReturn(__LINE__,'收入项写入失败');
            }

        }

        if(in_array($contractPropertyId,$ykPropertyClassId)&&$contractManage['effect_date']>='2018-01-01') {//云客类且开通时间大于2018-01-01开通增加收入
            $SummaryArrForLease = $this->getContractOrderSummaryByDateAndLeaseById($contract_id,$toReceivable = true);
            $this->putLog('$YkSummaryArrForLease=>'.json_encode($SummaryArrForLease,true),__METHOD__,$SummaryArrForLease);

            if($SummaryArrForLease['status'] === false){
                return self::setAndReturn(__LINE__,$SummaryArrForLease['msg']);
            }

            $resultAdd = $this->submitRevenueByEstablish($SummaryArrForLease,$contract_id,'yk');
            $this->putLog('YkSubmitRevenueByEstablish=>'.$resultAdd,__METHOD__,$resultAdd);

            if($resultAdd === false){
                return self::setAndReturn(__LINE__,'收入项写入失败');
            }
        }
    }


    /**
     * 通过参数获得contarctapplicationid
     *
     */
    public function sureAuthorizeList($arr)
    {

        if(!empty($arr['is_from_tenant'])&&$arr['is_from_tenant'] == 1){
            //租户过来的产品需要将合同编号转id
            $contractManageInfo = ContractManageRepository::getContractManageModelByContractNum($arr['contract_num']);
            $arr['contract_id'] = $contractManageInfo->contract_id;
        }

        //获取传递过来点appid
        $arr['application_id'] = $arr['apply_application_id'];

        //格式化租期
        $rent_period = (strtotime($arr['end_on'])-strtotime($arr['begin_on']))/3600/24/30;
        $rent_period = $this->formatLease($rent_period);
        $arr['rent_period'] = $rent_period;

        $arr['product_type'] = $arr['contract_type'];

        $myscrmContractApplicationInfo = $this->authorizationValidateRulesBy($arr);
        $this->putLog('authorizationValidateRulesBy_arr=>'.json_encode($arr),__METHOD__,$myscrmContractApplicationInfo);

        $arr['contract_application_id'] = $myscrmContractApplicationInfo['contract_application_id'];

        //TODO 需要返回业绩的结算金计算出来给云建写入授权表 同时切记要去掉以前修改授权表里的结算金逻辑

        $settlement_amount = MyscrmOrganizationToAuthorizeEntity::calculationSettlementAmount($arr);
        $sign_amount = MyscrmOrganizationToAuthorizeEntity::calculationSignAmount($arr);

        $res = [
            'contract_application_id'=>$arr['contract_application_id'],
            'settlement_amount'=>$settlement_amount,
            'sign_amount'=>$sign_amount,
        ];

        $this->putLog('return_cpi_settlement=>'.json_encode($res),__METHOD__,$res);

        //cpi 不存在要返回false 结算有肯能为0因此不判断
        return empty($arr['contract_application_id'])?false:$res;

    }


    public function putLog($msg,$method,$res)
    {
        $time = microtime(true);
        $log = new FileTarget();
        $day = date('Y-m-d');
        $log->logFile = Yii::$app->getRuntimePath() . '/logs/author-'.$day.'.log';

        $erroCode = empty($res)?1:0;

        $log->messages[] = [$msg,$erroCode,$method,$time];
        $log->export();
    }

    //坏味道修复

    /**
     * 依据uniqueName 转换获取对应产品APPID
     */
    public function getApplicationInfoByAuthorizeUniqueName($uniqueName)
    {
        return MyscrmContractApplicationService::getApplicationInfoByAuthorizeUniqueName($uniqueName);
    }

    /**
     * 依据合同编号返回合同信息
     */
    public function getContractManageModelByContractNum($contract_num)
    {
        return  ContractManageRepository::getContractManageModelByContractNum($contract_num);
    }


    /**
     * 租户中心过来数据进行合法性校验
     */
    public function authorizationCheck($item,$arr)
    {

        //坏味道修复

        $arr = [
            'contract_num'=>$arr['contract_num'],//增加用 修改也要传合同id
            'establish_time' => $arr['establish_time'],//开通时间
            //坏味道修复
            'application_id' => $item->apply_application_id,//明源云客电子商务平台-“快码传播”（项目） myscrm_application_info
            //坏味道修复
            'application_name_cdb' => $item->friendly_name,//明源云客电子商务平台-“快码传播”（项目） myscrm_application_info
            'unique_name' => $item->unique_name,//租户管理推过来的数据是没有appid 因此需要unique_name 去 app_info 表找对应关系 确定是否可以开通
            'begin_on' => $arr['begin_on'],//租期开始
            'end_on' => $arr['end_on'],//租期结束
            'total_num' =>$item->total_num,//开通数目
            'product_type' => $arr['contract_type'],//产品属性
            'application_id_cfg' => $item->id,//租户管理产品id
            'handleType' => $arr['handleType'],//租户管理对数据的处理方式 新增还是修改
        ];

        //TODO  需要将合同编号转合同id
        $contractManage = new ContractManageRepository();
        $contractManage = $contractManage->getContractManageArrByCode($arr['contract_num']);
        $arr['contract_id'] = $contractManage['contract_id'];

        if(empty($arr['contract_id'])){//录入假合同
            return true;
        }

        //TODO 判断合同状态确定是否允许开通
        $baseData = $this->getContractInfo($arr['contract_id']);

        //时间格式化成年月日 以防万一
        $arr['establish_time'] = date("Y-m-d",strtotime($arr['establish_time']));
        $applicationInfoAtContractDB = MyscrmContractApplicationService::getApplicationInfoByApplicationId($arr['application_id']);

        //格式化租期
        $rent_period = (strtotime($arr['end_on'])-strtotime($arr['begin_on']))/3600/24/30;
        $rent_period = $this->formatLease($rent_period);
        $arr['rent_period'] = $rent_period;

        $matching_rule = $applicationInfoAtContractDB['matching_rule'];
        $delivery_rules = $applicationInfoAtContractDB['delivery_rules'];

        $myscrmContractApplicationInfo = $this->authorizationValidateRules($arr);

        $this->putLog('authorizationValidateRules=>'.$arr,__METHOD__,$myscrmContractApplicationInfo);

        $this->putLog('$myscrmContractApplicationInfo=>'.$myscrmContractApplicationInfo,__METHOD__,$myscrmContractApplicationInfo);

        $product_type = null;

        switch ($arr['product_type']){

            case 1:
                $product_type = '新增';
                break;
            case 2:
                $product_type = '增购';
                break;
            case 3:
                $product_type = '续签';
                break;
        }

        //表示并没有下订单
        if(empty($myscrmContractApplicationInfo)){
            return self::setAndReturn(__LINE__, '合同未签约该产品'.'&nbsp<br>产品名:'.$arr['application_name_cdb'].'&nbsp<br>租期:'.$rent_period.'月'.'&nbsp<br>合同属性:'.$product_type);
        }

        //得到已经开通的产品
        $AlreadyAuthorized = $this->getContractOrganizationInfo($arr['contract_id'],$getType = true);

        $alredyHasApp = [];

        foreach($AlreadyAuthorized as $k=>$v){//依据租期,产品,产品类型进行分组
            $time = (strtotime($v['endOn'])-strtotime($v['beginOn']))/3600/24/30;
            $lease = $this->formatLease($time);
            if(!isset($alredyHasApp[$v['ApplicationId'].$lease.$v['ProductType']])){
                $alredyHasApp[$v['ApplicationId'].'--'.$lease.'--'.$v['ProductType']]=$v;
            }
        }

        $alredyHasAppKey = array_keys($alredyHasApp);

        //当前需要开通的产品
        $commitLease = (strtotime($arr['end_on'])-strtotime($arr['begin_on']))/3600/24/30;
        $commitLease = $this->formatLease($commitLease);
        $commitApp = $arr['application_id'].'--'.$commitLease.'--'.$arr['product_type'];

        $res = in_array($commitApp,$alredyHasAppKey);

        if($res&&empty($arr['id'])&&($matching_rule == 2 || $matching_rule == 3) &&$arr['total_num']>0){//已经开通且是没租期的那种 不可增加
            return self::setAndReturn(__LINE__, '已经开通的不可重复增加'.'&nbsp<br>产品名:'.$arr['application_name_cdb'].'&nbsp<br>租期:'.$rent_period.'月'.'&nbsp<br>合同属性:'.$product_type);
        }


        $revenue = $this->getRevenueByTime($arr['contract_id'],$arr['begin_on'],$arr['end_on'],$arr['establish_time']);

        if(!empty($revenue)){

            $recognitionList = RevenueRecognitionRepository::getRevenueRecognitionListByRevenueId($revenue['revenue_id']);
            if(!empty($recognitionList)) {
                return self::setAndReturn(__LINE__,'该合同下'.$revenue['income_code'].'已结转');
            }

            /*$stateXml = ErpInterfaceService::getRevenueByRevenueId($revenue['revenue_id']);
            $stateArr = self::xmlToArray($stateXml);
            if($stateArr[0] !=='未推送'){
                return self::setAndReturn(__LINE__,'该合同下'.$revenue['income_code'].$stateArr[0]);
            }*/

        }

        //TODO 那种有租期如果开通时间相同 租期也相同 项目数也相同是是否也不允许开通呢？
        return true;

    }


    /**
     * 依据条件判断该合同下该收入是否已经结转或推送
     * @author zhoud01
     * @since 2017-10-26
     *
     */
    public function revenueIsSendByContractTime($contractId,$beginOn,$endOn,$establishTime){
        $revenue = $this->getRevenueByTime($contractId,$beginOn,$endOn,$establishTime);
        $stateXml = ErpInterfaceService::getRevenueByRevenueId($revenue['revenue_id']);
        return self::xmlToArray($stateXml);
    }



    /**
     * 租期计算公式
     * @author zhoud01
     * @since 2017-8-2
     *
     */
    public function formatLease($time)
    {
        $time = $time<1?1:$time;
        //坏味道修复
        return (int)round($time);

    }

    /**
     * 授权规则校验
     * @author zhoud01
     * @since 2017-8-2
     *
     */
    public function authorizationValidateRules($arr){

        $applicationInfoAtContractDB = MyscrmContractApplicationService::getApplicationInfoByApplicationId($arr['application_id']);
        $matching_rule = $applicationInfoAtContractDB['matching_rule'];


        //租户管理中的开通产品
        $arr['contract_num'] = $arr['contract_code'];
        //时间格式化成年月日 以防万一
        $arr['establish_time'] = date("Y-m-d",strtotime($arr['establish_time']));
        $rent_period = (strtotime($arr['end_on'])-strtotime($arr['begin_on']))/3600/24/30;
        //格式化租期
        $rent_period = $this->formatLease($rent_period);
        $contract_type = $arr['product_type'];

        $myscrmContractApplicationEntity = new ContractApplicationEntity();

        $where1 = [
            'contract_id' => $arr['contract_id'],
            'application_id' => $arr['application_id'],
            'rent_period' => $rent_period,
            'contract_type' => $contract_type,
        ];

        $where2 = [
            'contract_id' => $arr['contract_id'],
            'application_id' => $arr['application_id'],
            'contract_type' => $contract_type,
        ];


        $where3 = [
            'contract_id' => $arr['contract_id'],
            'application_id' => $arr['application_id'],
        ];

        $where = [];

        if($matching_rule == 1){
            $where = $where1;
        }

        if($matching_rule == 2){
            $where = $where2;
        }

        if($matching_rule == 3){
            $where = $where3;
        }

        if(!empty($where)){
            $res = $myscrmContractApplicationEntity->find()->where($where)->asArray()->one();
        }

        $this->putLog('$arr=>'.json_encode($arr,true),__METHOD__,$res);
        $this->putLog('$res=>'.json_encode($where,true),__METHOD__,$res);
        $this->putLog('$matching_rule=>'.$matching_rule,__METHOD__,$res);
        $this->putLog('$myscrmContractApplicationEntity=>'.json_encode($res,true),__METHOD__,$res);

        return $res;

    }

    /**
     * 授权规则校验
     * @author zhoud01
     * @since 2017-8-2
     *
     */
    public function authorizationValidateRulesBy($arr){

        $applicationInfoAtContractDB = MyscrmContractApplicationService::getApplicationInfoByApplicationId($arr['application_id']);
        $matching_rule = $applicationInfoAtContractDB['matching_rule'];
        $rent_period = (strtotime($arr['end_on'])-strtotime($arr['begin_on']))/3600/24/30;
        //格式化租期
        $rent_period = $this->formatLease($rent_period);
        $contract_type = $arr['product_type'];
        $myscrmContractApplicationEntity = new ContractApplicationEntity();

        $where1 = [
            'contract_id' => $arr['contract_id'],
            'application_id' => $arr['application_id'],
            'rent_period' => $rent_period,
            'contract_type' => $contract_type,
        ];

        $where2 = [
            'contract_id' => $arr['contract_id'],
            'application_id' => $arr['application_id'],
            'contract_type' => $contract_type,
        ];

        $where3 = [
            'contract_id' => $arr['contract_id'],
            'application_id' => $arr['application_id'],
        ];

        $where = [];

        if($matching_rule == 1){
            $where = $where1;
        }

        if($matching_rule == 2){
            $where = $where2;
        }

        if($matching_rule == 3){
            $where = $where3;
        }

        if(!empty($where)){
            $res = $myscrmContractApplicationEntity->find()->where($where)->asArray()->one();
        }

        $this->putLog('$arr=>'.json_encode($arr,true),__METHOD__,$res);
        $this->putLog('$res=>'.json_encode($where,true),__METHOD__,$res);
        $this->putLog('$matching_rule=>'.$matching_rule,__METHOD__,$res);
        $this->putLog('$myscrmContractApplicationEntity=>'.json_encode($res,true),__METHOD__,$res);

        return $res;

    }



    /**
     * 获取合同授权按日期&租期汇总
     */
    public function actionGetContractOrderSummaryByDateAndLease($arr,$toReceivable = false)
    {
        $contractId = $arr['contract_id'];

        //TODO 模拟云建推送
        $GetContractOrderSummaryInfo = json_decode($arr['authorize']);

        //TODO ID 用于表示每一条独立
        $arr = [];
        foreach ($GetContractOrderSummaryInfo as $key=>$item){

            $item = get_object_vars($item);
            $application_id = $item['ApplicationId'];
            $application_info_id = $item['application_info_id'];//合同库产品info

            //需要做兼容处理 $application_id 找不到结果 就用 $apply_application_id
            $ApplicationInfo = $this->GetApplicationInfoByApplicationId($application_id);//配置库原id
            $ApplicationInfo = empty($ApplicationInfo)?$this->GetApplicationInfoByApplicationId($application_info_id):$ApplicationInfo;

            $item['applicationName'] = $ApplicationInfo['application_name'];
            $item['summaryReceived'] = $item['SettlementAmount'];
            $item['signAmount'] = $item['SignAmount'];
            $item['date'] = date("Y-m-d",strtotime($item['EstablishTime']));

            $item['buss_type_id'] = $ApplicationInfo['buss_type_id'];

            if(empty($item['buss_type_id'])){ //TODO revenue_type 字段值为0 则不汇总且提示有问题

                $msg = $item['applicationName'].':<br />业务收入项字段值为0或者为空';

                return [
                    'status'=>false,
                    'msg'=>$msg,
                ];
            }

            $arr[$key] =$item;
        }

        $result = [];
        foreach($arr as $v){

            if(!isset($result[$v['EstablishTime'].'--'.$v['BeginOn'].'--'.$v['EndOn'].'--'.$v['buss_type_id']])){
                $result[$v['EstablishTime'].'--'.$v['BeginOn'].'--'.$v['EndOn'].'--'.$v['buss_type_id']]=$v;
                $result[$v['EstablishTime'].'--'.$v['BeginOn'].'--'.$v['EndOn'].'--'.$v['buss_type_id']]['contractId'] = $contractId;
            }else{
                $result[$v['EstablishTime'].'--'.$v['BeginOn'].'--'.$v['EndOn'].'--'.$v['buss_type_id']]['summaryReceived']+=$v['summaryReceived'];
                $result[$v['EstablishTime'].'--'.$v['BeginOn'].'--'.$v['EndOn'].'--'.$v['buss_type_id']]['signAmount']+=$v['signAmount'];
                $result[$v['EstablishTime'].'--'.$v['BeginOn'].'--'.$v['EndOn'].'--'.$v['buss_type_id']]['ApplicationId'].=','.$v['ApplicationId'];
                $result[$v['EstablishTime'].'--'.$v['BeginOn'].'--'.$v['EndOn'].'--'.$v['buss_type_id']]['ProductType'].=','.$v['ProductType'];
                $result[$v['EstablishTime'].'--'.$v['BeginOn'].'--'.$v['EndOn'].'--'.$v['buss_type_id']]['Id'].=','.$v['Id'];
                $result[$v['EstablishTime'].'--'.$v['BeginOn'].'--'.$v['EndOn'].'--'.$v['buss_type_id']]['applicationName'].=','.$v['applicationName'];
                $result[$v['EstablishTime'].'--'.$v['BeginOn'].'--'.$v['EndOn'].'--'.$v['buss_type_id']]['contractId'] = $contractId;
            }


        }

        $result = array_values($result);

        if(!empty($toReceivable)){
            return $result;
        }

    }


    /**
     * 获取合同授权按日期汇总
     */
    public function actionGetContractOrderSummary($arrs,$toReceivable = false)
    {
        $contractId = $arrs['contract_id'];

        $GetContractOrderSummaryInfo = json_decode($arrs['authorize']);
        $arr = [];
        foreach ($GetContractOrderSummaryInfo as $key=>$item){

            $item = get_object_vars($item);
            $application_id = $item['ApplicationId'];//配置库原id
            $application_info_id = $item['application_info_id'];//合同库产品info

            //需要做兼容处理 $application_id 找不到结果 就用 $apply_application_id
            $ApplicationInfo = $this->GetApplicationInfoByApplicationId($application_id);
            $ApplicationInfo = empty($ApplicationInfo)?$this->GetApplicationInfoByApplicationId($application_info_id):$ApplicationInfo;

            $applicationInfo = MyscrmApplicationRepository::getApplicationByApplicationId($application_id);

            $FriendlyName = $applicationInfo->FriendlyName;
            $application_name = $ApplicationInfo['application_name'];

            if(!empty($FriendlyName)) {
                $item['applicationName'] = $FriendlyName;
            }

            if(!empty($application_name)){
                $item['applicationName'] = $application_name;
            }

            if(empty($FriendlyName) && empty($application_name)){
                $item['applicationName'] = '';
            }

            $item['summaryReceived'] = $item['SettlementAmount'];
            $item['date'] = date("Y-m-d",strtotime($item['EstablishTime']));

            $item['buss_type_id'] = $ApplicationInfo['buss_type_id'];
            if(empty($item['buss_type_id'])){ //TODO revenue_type 字段值为0 则不汇总且提示有问题

                $msg = $item['applicationName'].':<br />业务收入项字段值为0或者为空';

                return [
                   'status'=>false,
                   'msg'=>$msg,
                ];
            }

            $arr[$key] =$item;
        }

        $result = [];
        $appName = [];
        $productType = [];

        foreach($arr as $v){
            if(!isset($result[$v['EstablishTime'].'--'.$v['buss_type_id']])){
                $result[$v['EstablishTime'].'--'.$v['buss_type_id']]=$v;
                $result[$v['EstablishTime'].'--'.$v['buss_type_id']]['contractId'] = $contractId;
                $appName[$v['EstablishTime'].'--'.$v['buss_type_id']][$v['applicationName']] = 1;
                $productType[$v['EstablishTime'].'--'.$v['buss_type_id']][$v['ProductType']] = 1;
                $result[$v['EstablishTime'].'--'.$v['buss_type_id']]['ProductType'] = join(',',array_keys($productType[$v['EstablishTime'].'--'.$v['buss_type_id']]));
            }else{
                $result[$v['EstablishTime'].'--'.$v['buss_type_id']]['summaryReceived']+=$v['summaryReceived'];
                $result[$v['EstablishTime'].'--'.$v['buss_type_id']]['ApplicationId'].=','.$v['ApplicationId'];
                $productType[$v['EstablishTime'].'--'.$v['buss_type_id']][$v['ProductType']] = 1;
                $result[$v['EstablishTime'].'--'.$v['buss_type_id']]['ProductType'] = join(',',array_keys($productType[$v['EstablishTime'].'--'.$v['buss_type_id']]));
                $result[$v['EstablishTime'].'--'.$v['buss_type_id']]['Id'].=','.$v['Id'];
                $appName[$v['EstablishTime'].'--'.$v['buss_type_id']][$v['applicationName']] = 1;
                $result[$v['EstablishTime'].'--'.$v['buss_type_id']]['applicationName'] = join(',',array_keys($appName[$v['EstablishTime'].'--'.$v['buss_type_id']]));
                $result[$v['EstablishTime'].'--'.$v['buss_type_id']]['contractId'] = $contractId;
            }
        }

        if(!empty($toReceivable)){
            return $result;
        }

    }

    /**
     * 获取合同授权按日期&租期汇总
     */
    public function getContractOrderSummaryByDateAndLeaseById($contractId,$toReceivable = false)
    {

        $contractNum = $this->getContractNum($contractId);//租户管理中的开通产品
        $GetContractOrderSummaryInfo = $this->GetContractOrderSummary($contractNum);//租户管理中的开通产品


        $arr = [];
        foreach ($GetContractOrderSummaryInfo as $key=>$item){

            $application_id = $item['ApplicationId'];
            $application_info_id = $item['application_info_id'];//合同库产品info

            //需要做兼容处理 $application_id 找不到结果 就用 $apply_application_id
            $ApplicationInfo = $this->GetApplicationInfoByApplicationId($application_id);
            $ApplicationInfo = empty($ApplicationInfo)?$this->GetApplicationInfoByApplicationId($application_info_id):$ApplicationInfo;

            $item['applicationName'] = $ApplicationInfo['application_name'];
            $item['summaryReceived'] = $item['SettlementAmount'];
            $item['date'] = date("Y-m-d",strtotime($item['EstablishTime']));
            $item['signAmount'] = $item['SignAmount'];
            $item['buss_type_id'] = $ApplicationInfo['buss_type_id'];

            if(empty($item['buss_type_id'])){ //TODO revenue_type 字段值为0 则不汇总且提示有问题

                $msg = $item['applicationName'].':<br />业务收入项字段值为0或者为空';

                return [
                    'status'=>false,
                    'msg'=>$msg,
                ];
            }

            $arr[$key] =$item;
        }

        $result = [];
        foreach($arr as $v){

            if(!isset($result[$v['PerformanceAccountingTime'].'--'.$v['BeginOn'].'--'.$v['EndOn'].'--'.$v['buss_type_id']])){
                $result[$v['PerformanceAccountingTime'].'--'.$v['BeginOn'].'--'.$v['EndOn'].'--'.$v['buss_type_id']]=$v;
                $result[$v['PerformanceAccountingTime'].'--'.$v['BeginOn'].'--'.$v['EndOn'].'--'.$v['buss_type_id']]['contractId'] = $contractId;
            }else{
                $result[$v['PerformanceAccountingTime'].'--'.$v['BeginOn'].'--'.$v['EndOn'].'--'.$v['buss_type_id']]['summaryReceived']+=$v['summaryReceived'];
                $result[$v['PerformanceAccountingTime'].'--'.$v['BeginOn'].'--'.$v['EndOn'].'--'.$v['buss_type_id']]['signAmount']+=$v['signAmount'];
                $result[$v['PerformanceAccountingTime'].'--'.$v['BeginOn'].'--'.$v['EndOn'].'--'.$v['buss_type_id']]['ApplicationId'].=','.$v['ApplicationId'];
                $result[$v['PerformanceAccountingTime'].'--'.$v['BeginOn'].'--'.$v['EndOn'].'--'.$v['buss_type_id']]['ProductType'].=','.$v['ProductType'];
                $result[$v['PerformanceAccountingTime'].'--'.$v['BeginOn'].'--'.$v['EndOn'].'--'.$v['buss_type_id']]['Id'].=','.$v['Id'];
                $result[$v['PerformanceAccountingTime'].'--'.$v['BeginOn'].'--'.$v['EndOn'].'--'.$v['buss_type_id']]['applicationName'].=','.$v['applicationName'];
                $result[$v['PerformanceAccountingTime'].'--'.$v['BeginOn'].'--'.$v['EndOn'].'--'.$v['buss_type_id']]['contractId'] = $contractId;
            }

        }

        $result = array_values($result);

        if(!empty($toReceivable)){
            return $result;
        }

    }


    /**
     * 获取合同授权按日期汇总
     */
    public function getContractOrderSummaryById($contractId,$toReceivable = false)
    {

        $contractNum = $this->getContractNum($contractId);//租户管理中的开通产品
        $GetContractOrderSummaryInfo = $this->GetContractOrderSummary($contractNum);//租户管理中的开通产品

        $arr = [];
        foreach ($GetContractOrderSummaryInfo as $key=>$item){

            $application_id = $item['ApplicationId'];
            $application_info_id = $item['application_info_id'];//合同库产品info

            //需要做兼容处理 $application_id 找不到结果 就用 $apply_application_id
            $ApplicationInfo = $this->GetApplicationInfoByApplicationId($application_id);
            $ApplicationInfo = empty($ApplicationInfo)?$this->GetApplicationInfoByApplicationId($application_info_id):$ApplicationInfo;

            $applicationInfo = MyscrmApplicationRepository::getApplicationByApplicationId($application_id);

            $appDataInfo = MyscrmContractApplicationService::getApplicationInfoByAuthorizeUniqueName($applicationInfo->UniqueName,$item['IsQdAdvanced']);//查真名用

            $FriendlyName = $applicationInfo->FriendlyName;

            $application_name = $appDataInfo['application_name'];


            $contractAndApp = ContractApplicationRepository::getContractApplicationAppId($item['ContractApplicationId']);//订单产品信息
            $applicationInfoAtContractDB = MyscrmContractApplicationService::getApplicationInfoByApplicationId($contractAndApp->application_id);//所有产品

            if(!empty($FriendlyName)) {

                $item['applicationName'] = $applicationInfoAtContractDB['application_name'];
                if(empty($applicationInfoAtContractDB['application_name'])){
                    $item['applicationName'] = $FriendlyName;
                }
            }


            if(empty($applicationInfo)){
                $item['applicationName'] = $ApplicationInfo['application_name'];
            }

            if(empty($FriendlyName) && empty($application_name)){
                $item['applicationName'] = '';
            }

            $item['summaryReceived'] = $item['SettlementAmount'];
            $item['date'] = date("Y-m-d",strtotime($item['EstablishTime']));

            $item['buss_type_id'] = $ApplicationInfo['buss_type_id'];

            if(empty($item['buss_type_id'])){ //TODO revenue_type 字段值为0 则不汇总且提示有问题

                $msg = $item['applicationName'].':<br />业务收入项字段值为0或者为空';

                return [
                    'status'=>false,
                    'msg'=>$msg,
                ];
            }

            $arr[$key] =$item;
        }

        $result = [];
        $appName = [];
        $productType = [];

        foreach($arr as $v){
            if(!isset($result[$v['EstablishTime'].'--'.$v['buss_type_id']])){
                $result[$v['EstablishTime'].'--'.$v['buss_type_id']]=$v;
                $result[$v['EstablishTime'].'--'.$v['buss_type_id']]['contractId'] = $contractId;
                $appName[$v['EstablishTime'].'--'.$v['buss_type_id']][$v['applicationName']] = 1;
                $productType[$v['EstablishTime'].'--'.$v['buss_type_id']][$v['ProductType']] = 1;
                $result[$v['EstablishTime'].'--'.$v['buss_type_id']]['ProductType'] = join(',',array_keys($productType[$v['EstablishTime'].'--'.$v['buss_type_id']]));
            }else{
                $result[$v['EstablishTime'].'--'.$v['buss_type_id']]['summaryReceived']+=$v['summaryReceived'];
                $result[$v['EstablishTime'].'--'.$v['buss_type_id']]['ApplicationId'].=','.$v['ApplicationId'];
                $productType[$v['EstablishTime'].'--'.$v['buss_type_id']][$v['ProductType']] = 1;
                $result[$v['EstablishTime'].'--'.$v['buss_type_id']]['ProductType'] = join(',',array_keys($productType[$v['EstablishTime'].'--'.$v['buss_type_id']]));
                $result[$v['EstablishTime'].'--'.$v['buss_type_id']]['Id'].=','.$v['Id'];
                $appName[$v['EstablishTime'].'--'.$v['buss_type_id']][$v['applicationName']] = 1;
                $result[$v['EstablishTime'].'--'.$v['buss_type_id']]['applicationName'] = join(',',array_keys($appName[$v['EstablishTime'].'--'.$v['buss_type_id']]));
                $result[$v['EstablishTime'].'--'.$v['buss_type_id']]['contractId'] = $contractId;
            }
        }

        if(!empty($toReceivable)){
            return $result;
        }

    }


    private function maintainDistributionAmount($contractId)
    {
        $contractEntity = ContractManageRepository::getContractManageModelByContractId($contractId);

        //签约人ID
        //如果产品信息中的签约\结算\回款金额有变动,则修改签约人的分摊信息
        //仅限saas的业绩
        $signUserId = $contractEntity->sign_people_id;

        $allProductData = $this->getContractApplicationListGroupByContractType($contractId);

        $distributionListGroupBy = $this->getDistributionAmountListGroupByContractType($contractId);

        $allContractType = [1, 2, 3];
        $allIsSaasType = [0, 1];

        foreach ($allContractType as $contractType){

            foreach ($allIsSaasType as $saasType){

                $productSign = isset($allProductData[$contractType][$saasType]['sign_average_amount']) ? $allProductData[$contractType][$saasType]['sign_average_amount'] : 0;
                $productSettlement = isset($allProductData[$contractType][$saasType]['settlement_average_amount']) ? $allProductData[$contractType][$saasType]['settlement_average_amount'] : 0;

                $distributionSign = isset($distributionListGroupBy[$contractType][$saasType]['sign_average_amount']) ? $distributionListGroupBy[$contractType][$saasType]['sign_average_amount'] : 0;
                $distributionSettlement = isset($distributionListGroupBy[$contractType][$saasType]['settlement_average_amount']) ? $distributionListGroupBy[$contractType][$saasType]['settlement_average_amount'] : 0;

                //判断是否存在该合同类型的分摊金额,没则新增,有则修改
                $checkResult = ContractManageRepository::checkHasDistributionByContractIdAndType($contractId, $contractType, $saasType);

                if ($checkResult === false && ($productSign > 0 || $productSettlement > 0)) {
                    $addResult = $this->addDistributionByContractType($contractEntity, $contractType, $saasType, $productSign, $productSettlement);
                    if ($addResult === false) {
                        return $this->setAndReturn(__LINE__, $this->getErrMsg());
                    }
                } else {
                    if ($productSign != $distributionSign) {
                        $maintainSignResult = $this->maintainAmount($contractType, $contractId, $saasType, $signUserId, $productSign, $distributionSign, 'sign_average_amount');
                        if ($maintainSignResult === false) {
                            return $this->setAndReturn(__LINE__, '维护签约分摊金额失败');
                        }
                    }

                    if ($productSettlement != $distributionSettlement) {
                        $maintainSettlementResult = $this->maintainAmount($contractType, $contractId, $saasType, $signUserId, $productSettlement, $distributionSettlement, 'settlement_average_amount');
                        if ($maintainSettlementResult === false) {
                            return $this->setAndReturn(__LINE__, '维护结算分摊金额失败');
                        }
                    }
                }
            }

        }

        return true;
    }

    /**
     * 按合同属性、是否saas添加分摊金额
     * @param $contractInfo
     * @param $contractType
     * @param $saasType
     * @param $signAmount
     * @param $settlementAmount
     * @return bool
     */
    private function addDistributionByContractType($contractInfo, $contractType, $saasType, $signAmount, $settlementAmount)
    {
        //签约金额和结算金额都为0，不增加记录
        if (($signAmount + $settlementAmount) <= 0) {
            return true;
        }

        $distribution = [
            'sign_average_amount' => $signAmount,
            'settlement_average_amount' => $settlementAmount,
            'receivable_average_amount' => 0,
            'contract_type' => $contractType,
            'user_id' => $contractInfo['sign_people_id'],
            'area_id' => $contractInfo['area_id'],
            'department_id' => $contractInfo['sign_people_department_by'],
            'is_saas' => $saasType,
        ];

        if ($saasType == 0) {//非saas业绩默认归属人
            $defaultBelongUserId = \Yii::$app->params['notSaasBelongUserId'];

            $userInfo = ErpUserRepository::getUserInfoById($defaultBelongUserId);

            $distribution['user_id'] = $defaultBelongUserId;
            $distribution['area_id'] = $userInfo['BUGUID'];
            $distribution['department_id'] = $userInfo["DepartmentGUID"];
        }

        $addResult = ContractManageRepository::addDistribution($contractInfo['contract_id'], $contractInfo['input_date'], $distribution);
        if ($addResult === false) {
            return $this->setAndReturn(__LINE__, '新增签约分摊金额失败');
        }

        return true;
    }

    private function maintainAmount($contractType, $contractId, $saasType, $signUserId, $productSign, $distributionSign, $type = 'sign_average_amount')
    {
        $distributionEntity = ContractManageRepository::getDistributionEntity($contractId, $contractType, $saasType);

        $diff = $productSign - $distributionSign;

        if ($diff > 0) {
            $distributionEntity->$type = $distributionEntity->$type + $diff;
            return ContractManageRepository::updateDistributionEntity($distributionEntity);
        } else {//差值小于0需要减少的情况,要确保单个分摊人减少后不能是负数

            if ($distributionEntity->$type + $diff <= 0) {
                $distributionEntity->$type = 0;
                ContractManageRepository::updateDistributionEntity($distributionEntity);

                return $this->deleteDistributionAmount($distributionEntity->$type + $diff, $contractType, $contractId, [$signUserId], $type);
            } else {
                $distributionEntity->$type = $diff;
                ContractManageRepository::updateDistributionEntity($distributionEntity);

                return true;
            }
        }
    }

    private function deleteDistributionAmount($diff, $contractType, $contractId, $withoutUserIds, $type)
    {
        if ($diff == 0) {
            return true;
        }

        $distributionEntity = ContractManageRepository::getDistributionEntityWithoutUserId($contractId, $contractType, $withoutUserIds);
        if (!$distributionEntity) {
            return true;
        }

        //减去当前的分摊人的金额后仍然小于0,则递归,直到需要减去的金额消耗完毕
        if ($distributionEntity->$type + $diff < 0) {
            $distributionEntity->$type = 0;
            ContractManageRepository::updateDistributionEntity($distributionEntity);

            array_push($withoutUserIds, $distributionEntity->user_id);

            return $this->deleteDistributionAmount($distributionEntity->$type + $diff, $contractId, $contractType, $withoutUserIds, $type);
        } else {
            $distributionEntity->$type = $distributionEntity->$type + $diff;
            ContractManageRepository::updateDistributionEntity($distributionEntity);

            return true;
        }
    }

    private function getDistributionAmountListGroupByContractType($contractId)
    {
        $allDistributionAmountList = ContractManageRepository::getDistributionByContractId($contractId);

        $ret = [];
        foreach ($allDistributionAmountList as $distributionAmount) {
            $contractType = $distributionAmount['contract_type'];
            $isSaas = $distributionAmount['is_saas'];

            if(isset($ret[$contractType][$isSaas]['sign_average_amount'])){
                $ret[$contractType][$isSaas]['sign_average_amount'] += $distributionAmount['sign_average_amount'];
            }else{
                $ret[$contractType][$isSaas]['sign_average_amount'] = $distributionAmount['sign_average_amount'];
            }

            if(isset($ret[$contractType][$isSaas]['settlement_average_amount'])){
                $ret[$contractType][$isSaas]['settlement_average_amount'] += $distributionAmount['settlement_average_amount'];
            }else{
                $ret[$contractType][$isSaas]['settlement_average_amount'] = $distributionAmount['settlement_average_amount'];
            }
        }

        return $ret;
    }

    private function getContractApplicationListGroupByContractType($contractId)
    {
        $allProductList = ContractApplicationRepository::getAllContractApplicationByContractId($contractId);
        $ret = [];
        foreach ($allProductList as $product) {
            if ($product['contract_type']) {
                $contractType = $product['contract_type'];
                $isSaas = $product['is_saas'];

                if(isset($ret[$contractType][$isSaas]['sign_average_amount'])){
                    $ret[$contractType][$isSaas]['sign_average_amount'] += $product['sign_average_amount'];
                }else{
                    $ret[$contractType][$isSaas]['sign_average_amount'] = $product['sign_average_amount'];
                }

                if(isset($ret[$contractType][$isSaas]['settlement_average_amount'])){
                    $ret[$contractType][$isSaas]['settlement_average_amount'] += $product['settlement_average_amount'];
                }else{
                    $ret[$contractType][$isSaas]['settlement_average_amount'] = $product['settlement_average_amount'];
                }
            }
        }

        return $ret;
    }

    /**
     * @param $contractId
     * @param $isForce
     * @return boolean
     *  原结算分摊金额：等于标准总额/产品标准总额合计*结算金额合计，可支持手动调整
     * 原产品租金分摊金额：等于标准总额/产品标准总额合计*产品租用金额（这俩字段都在基本信息-新增产品）
     * 原签约分摊金额：等于标准总额/产品标准总额合计*签约金额（这俩字段都在基本信息-新增产品）
     */
    public function calcApplicationAmount($contractId, $isForce = false,$Recalculate = false )
    {
        $contractManage = ContractManageRepository::getContractManageModelByContractId($contractId);

        if (empty($contractManage)) {
            return false;
        }

        //结算金额合计
        $balanceAmount = isset($contractManage["balance_amount"]) ? $contractManage["balance_amount"] : 0;

        $applicationData = ContractApplicationRepository::getAllContractApplicationByContractId($contractId);

        //产品标准总额合计
        $allAmount = ContractApplicationRepository::getAllAmountByContractId($contractId);
        foreach ($applicationData as $application) {
            $amount = !empty($application["amount"]) ? $application["amount"] : 0;
            $origin_settlement_average_amount = $application["origin_settlement_average_amount"];
            $origin_sign_average_amount = $application["origin_sign_average_amount"];
            $origin_product_average_amount = $application["origin_product_average_amount"];

            if ($allAmount != 0) {
                //计算 原结算分摊金额 判断是否相同,如果不相同则更新
                $origin_settlement_average_amount = round(($amount / $allAmount) * $balanceAmount);
                $settlement_average_amount = $origin_settlement_average_amount - $application["adjust_settlement_average_amount"];

                //计算 原产品租金分摊金额
                $sign_amount = !empty($contractManage["sign_amount"]) ? $contractManage["sign_amount"] : 0;
                $origin_sign_average_amount = round(($amount / $allAmount) * $sign_amount);
                $sign_average_amount = $origin_sign_average_amount - $application["adjust_sign_average_amount"];

                //计算 原签约分摊金额
                $rent_amount = !empty($contractManage["rent_amount"]) ? $contractManage["rent_amount"] : 0;
                $origin_product_average_amount = round(($amount / $allAmount) * $rent_amount);
                $product_average_amount = $origin_product_average_amount - $application["adjust_product_average_amount"];
            }

            //强制更新
            if ($isForce) {
                //如果有变更则更新
                if ($origin_settlement_average_amount != $application["origin_settlement_average_amount"]
                    || $origin_sign_average_amount != $application["origin_sign_average_amount"]
                    || $origin_product_average_amount != $application["origin_product_average_amount"]
                ) {
                    $data = [
                        "origin_settlement_average_amount" => $origin_settlement_average_amount,
                        "settlement_average_amount" => $settlement_average_amount,
                        "origin_sign_average_amount" => $origin_sign_average_amount,
                        "sign_average_amount" => $sign_average_amount,
                        "origin_product_average_amount" => $origin_product_average_amount,
                        "product_average_amount" => $product_average_amount,
                    ];

                    ContractApplicationRepository::updatedByPk($application["contract_application_id"], $data);

                }
            } else {
                //非强制更新,只有当为空值时才更新
                if (empty($application["origin_settlement_average_amount"])
                    || empty($application["origin_sign_average_amount"])
                    || empty($application["origin_product_average_amount"])
                ) {
                    $data = [
                        "origin_settlement_average_amount" => $origin_settlement_average_amount,
                        "settlement_average_amount" => $settlement_average_amount,
                        "origin_sign_average_amount" => $origin_sign_average_amount,
                        "sign_average_amount" => $sign_average_amount,
                        "origin_product_average_amount" => $origin_product_average_amount,
                        "product_average_amount" => $product_average_amount,
                    ];

                    ContractApplicationRepository::updatedByPk($application["contract_application_id"], $data);
                }
            }

        }

        if($Recalculate){

            //每次维护产品签约金额后,需要维护分摊金额
            //坏味道修复 原逻辑

            //$this->calculateDistributionAmount($contractId);
        }

        return true;
    }

    public function search($keyword, $pageNo, $pageSize)
    {
        return ContractManageRepository::search($keyword, $pageNo, $pageSize);
    }

    private function batchGetPropertyName()
    {
        $allPropertyNameInfo = ContractPropertyRepository::getAllContractPropertyList();
        $propertyNameGroupById = [];
        foreach ($allPropertyNameInfo as $property) {
            $propertyNameGroupById[$property['property_id']] = $property['property_name'];
        }

        return $propertyNameGroupById;
    }

    private function batchGetInvoiceBuName($data)
    {
        $invoice_company_ids = ArrayHelper::getColumn($data, 'invoice_company_id');
        $allInfo = InvoiceBusinessUnitRepository::getAllBuNameByCompanyIds($invoice_company_ids);
        $groupById = [];
        foreach ($allInfo as $info) {
            $groupById[$info['BUGUID']] = $info['BUName'];
        }

        return $groupById;
    }

    private function batchGetAreaName($data)
    {
        $areaIds = ArrayHelper::getColumn($data, 'area_id');
        $allAreaInfo = ErpBusinessUnitRepository::getAreaNameById($areaIds);
        $areaNameGroupById = [];
        foreach ($allAreaInfo as $area) {
            $areaNameGroupById[$area['BUGUID']] = $area['BUName'];
        }

        return $areaNameGroupById;
    }

    private function batchGetContractCategory($data)
    {
        $contractCategoryIds = ArrayHelper::getColumn($data, 'category_id');
        $contractCategoryInfo = ContractCategoryRepository::getAllCategoryNameByCategoryIds($contractCategoryIds);
        $contractCategoryById = [];
        foreach ($contractCategoryInfo as $contractCategory) {
            $contractCategoryById[$contractCategory['category_id']] = $contractCategory['category_name'];
        }

        return $contractCategoryById;
    }

    private function batchGetContractBigCategory($data)
    {
        $contractBigCategoryIds = ArrayHelper::getColumn($data, 'big_category_id');
        $contractBigCategoryInfo = ContractBigCategoryRepository::getAllContractBigCategoryNameByBigCategoryIds($contractBigCategoryIds);
        $contractBigCategoryById = [];
        foreach ($contractBigCategoryInfo as $contractBigCategory) {
            $contractBigCategoryById[$contractBigCategory['big_category_id']] = $contractBigCategory['big_category_name'];
        }

        return $contractBigCategoryById;
    }

    private function batchGetContractLittlerCategory($data)
    {
        $contractLittlerCategoryIds = ArrayHelper::getColumn($data, 'littler_category_id');
        $contractLittlerCategoryInfo = ContractLittlerCategoryRepository::getAllContractLittlerCategoryNameByLittlerCategoryIds($contractLittlerCategoryIds);
        $contractLittlerCategoryById = [];
        foreach ($contractLittlerCategoryInfo as $contractLittlerCategory) {
            $contractLittlerCategoryById[$contractLittlerCategory['littler_category_id']] = $contractLittlerCategory['littler_category_name'];
        }

        return $contractLittlerCategoryById;
    }

    private function batchGetUserNameByIds($data)
    {
        $contractSignPeopleIds = ArrayHelper::getColumn($data, 'sign_people_id', false);
        $belongByIds = ArrayHelper::getColumn($data, 'belong_by', false);
        $proposerIds = ArrayHelper::getColumn($data, 'proposer_id', false);
        $cdaUserIds = ArrayHelper::getColumn($data, 'contractDistributionAmountUserId', false);
        $contractSignPeopleIds = array_merge($contractSignPeopleIds, $belongByIds, $proposerIds, $cdaUserIds);

        $contractSignPeopleInfo = ErpUserRepository::getAllUserNameByUserGUIDs($contractSignPeopleIds);
        $contractSignPeopleGroupById = [];
        foreach ($contractSignPeopleInfo as $contractSignPeople) {
            $contractSignPeopleGroupById[$contractSignPeople['UserGUID']] = $contractSignPeople['UserName'];
        }

        return $contractSignPeopleGroupById;
    }

    private function batchGetDepartmentByIds($data)
    {
        $contractSignPeopleDepartmentIds = ArrayHelper::getColumn($data, 'sign_people_department_by', false);
        $contractDepartmentByIds = ArrayHelper::getColumn($data, 'department_by', false);
        $areaByIds = ArrayHelper::getColumn($data, 'area_by', false);
        $contractSignPeopleDepartmentIds = array_merge($contractSignPeopleDepartmentIds, $contractDepartmentByIds, $areaByIds);

        $contractSignPeopleDepartmentInfo = ErpBusinessUnitRepository::getAllBunameByBuguids($contractSignPeopleDepartmentIds);
        $contractSignPeopleDepartmentGroupById = [];
        foreach ($contractSignPeopleDepartmentInfo as $contractSignPeopleDepartment) {
            $contractSignPeopleDepartmentGroupById[$contractSignPeopleDepartment['BUGUID']] = $contractSignPeopleDepartment['BUName'];
        }

        return $contractSignPeopleDepartmentGroupById;
    }

    private function batchGetBillingAmountSum($contractIds)
    {
        $contractBillingAmountSumInfo = InvoiceRepository::getAllBillingAmountSumByContractIds($contractIds, 0);
        $contractBillingAmountSumGroupById = [];
        foreach ($contractBillingAmountSumInfo as $contractBillingAmountSum) {
            $contractBillingAmountSumGroupById[$contractBillingAmountSum['contract_id']] = $contractBillingAmountSum['billing_amount'];
        }

        return $contractBillingAmountSumGroupById;
    }

    private function batchGetReceiptAmountSum($contractIds)
    {
        $contractBillingAmountSumInfo = InvoiceRepository::getAllBillingAmountSumByContractIds($contractIds, 1);
        $contractBillingAmountSumGroupById = [];
        foreach ($contractBillingAmountSumInfo as $contractBillingAmountSum) {
            $contractBillingAmountSumGroupById[$contractBillingAmountSum['contract_id']] = $contractBillingAmountSum['billing_amount'];
        }

        return $contractBillingAmountSumGroupById;
    }

    private function batchGetReceivedAmountSum($contractIds)
    {
        $contractReceivedAmountSumInfo = ContractReceivableRepository::getAllReceivedAmountSumByContractIds($contractIds);
        $contractReceivedAmountSumGroupById = [];
        foreach ($contractReceivedAmountSumInfo as $contractReceivedAmountSum) {
            $contractReceivedAmountSumGroupById[$contractReceivedAmountSum['contract_id']] = $contractReceivedAmountSum['received_amount'];
        }

        return $contractReceivedAmountSumGroupById;
    }

    private function batchGetIsBadDebt($contractIds)
    {
        $contractIsBadDebtInfo = ContractReceivableRepository::getAllIsBadDebtByContractIds($contractIds);
        $contractIsBadDebtGroupById = [];
        foreach ($contractIsBadDebtInfo as $contractIsBadDebt) {
            $contractIsBadDebtGroupById[$contractIsBadDebt['contract_id']] = $contractIsBadDebt['is_bad_debt'];
        }

        return $contractIsBadDebtGroupById;
    }

    private function batchGetRepaymentCompany($data)
    {
        $repaymentCompanyIds = ArrayHelper::getColumn($data, 'repayment_company', false);
        $repaymentCompanyInfo = ContractCompanyRepository::getAllContractCompanyNameByCompanyIds($repaymentCompanyIds);
        $repaymentCompanyById = [];
        foreach ($repaymentCompanyInfo as $repaymentCompany) {
            $repaymentCompanyById[$repaymentCompany['company_id']] = $repaymentCompany['company_name'];
        }

        return $repaymentCompanyById;
    }

    private function batchGetBeginOnEndOn($contractCodes)
    {
        /** @var MyscrmContractRepository $contractRepository */
        $contractRepository = Yii::createObject(MyscrmContractRepository::className());
        $contractList = $contractRepository->getListByCodes($contractCodes);

        $contractGroupById = [];
        foreach ($contractList as $contract) {
            $contractGroupById[$contract['ContractNum']]['BeginOn'] = $contract['BeginOn'];
            $contractGroupById[$contract['ContractNum']]['EndOn'] = $contract['EndOn'];
        }

        return $contractGroupById;
    }

    private function batchGetApplicationName($contractIds) {
        $applicationNames = array();
        foreach ($contractIds as $contractId) {
            $applicationNames[$contractId] = ArrayHelper::getColumn(ContractApplicationRepository::getAllContractApplicationByContractId($contractId), 'application_name');
        }
        return $applicationNames;
    }

    private function getAuthorizationSummary($contractCode) {

        $arr = [];
        $result = [];

        foreach($this->GetContractOrderSummary($contractCode) as $key=>$item){
            $application_id = $item['ApplicationId'];
            $application_info_id = $item['application_info_id'];//合同库产品info
            //需要做兼容处理 $application_id 找不到结果 就用 $apply_application_id
            $ApplicationInfo = $this->GetApplicationInfoByApplicationId($application_id);
            $ApplicationInfo = empty($ApplicationInfo)?$this->GetApplicationInfoByApplicationId($application_info_id):$ApplicationInfo;
            $item['buss_type_id'] = $ApplicationInfo['buss_type_id'];
            $arr[$key] =$item;
        }

        foreach($arr as $k=>$v){
            if(!isset($result[$v['EstablishTime'].'--'.$v['buss_type_id']])){
                $result[$v['EstablishTime'].'--'.$v['buss_type_id']]=$v;
            }else{
                $result[$v['EstablishTime'].'--'.$v['buss_type_id']]['summaryReceived']+=$v['summaryReceived'];
            }
        }
        return $result;
    }

    /**
     * 根据合同编号获取首次开通时间
     * @param $contractCodes
     * @return array
     */
    private function batchGetFirstEstablishTime($contractCodes) {
       $firstEstablishTimes = array();
       foreach ($contractCodes as $contractCode) {
           $firstEstablishTimes[$contractCode] = ArrayHelper::getColumn(MyscrmContractRepository::getFirstEstablishTimeByContractNum($contractCode),'firstEstablishTime');
       }
       return $firstEstablishTimes;
    }

    private function multipleComparisons($num1,$num2){
        return empty($num1)?'无':($num1<$num2?'少':'');
    }

    /**
     * 发送合同的产品信息
     *
     * @param $contractId
     * @param $applicationId
     * @param $num
     * @return bool
     */
    public function sendContractApplication($contractId, $applicationId, $num)
    {
        $contractApplicationId = ContractApplicationRepository::getContractAppId($contractId, $applicationId);
        if($contractApplicationId != false){
            $pushParams = [
                'contract_id'       => $contractId,
                'application_id'    => $applicationId,
                'application_name'  => ApplicationInfoRepository::getApplicationNameByApplicationId($applicationId),
                'application_state' => $this->getContractApplicationStatus($contractId, $contractApplicationId),
                'number'            => $num,
            ];

            return ErpInterfaceService::pushAuthorizationToBusinessSystem($pushParams);
        }

        return true;
    }

    /**
     * 获取合同产品的出库状态
     * 从getContractInfo抽出来的
     *
     * @param $contractId
     * @param $contractApplicationId
     * @return string
     */
    public function getContractApplicationStatus($contractId, $contractApplicationId)
    {
        $AuthorizeNum = 0;
        $AuthorizeAmount = 0;

        $application = ContractApplicationRepository::getContractApplicationInfo($contractApplicationId);
        $application = array_merge($application, ApplicationInfoRepository::getApplicationInfoByApplicationId($application['application_id']));

        $adAmount = 0;
        $adList = $this->getAdOrganizationInfo($contractId);
        if(! empty($adList)){
            foreach ($adList as $v){
                $adAmount += $v['Money'];
            }
        }

        $getAuthorizeInfos = OrganizationToAuthorizeRepository::getAuthorizeNumByContractApplicationId($contractApplicationId);
        if(! empty($getAuthorizeInfos)){
            foreach ($getAuthorizeInfos as $getAuthorizeInfo ){
                $AuthorizeNum += $getAuthorizeInfo['TotalNum'];
                //TODO 获取结算金额
                $AuthorizeAmount +=$getAuthorizeInfo['SettlementAmount'];
                //TODO 获取产品类型(合同类型)
            }
        }
        if($application['application_id'] ==='2802105e-11ac-4191-9fbe-adf1d1945daa'){//广告类型取已经投放的金额

            $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); //获取model
            if (empty($contractModel)) {//合同不存在
                return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_EXISTS);
            }

            $AuthorizeNum = $adAmount;
            $application['authorization_numeric'] = (int)$contractModel->rent_amount;
        }

        //TODO 增加已出数目
        $application['alreadyOutNum'] = $AuthorizeNum;

        $application['settlementAmount'] = $AuthorizeAmount;
        //TODO 合同属性
        $application['productType'] = isset($getAuthorizeInfos[0]['ProductType']) ? $getAuthorizeInfos[0]['ProductType'] : '';//取第一条当合同属性即可

        $result = '未开始';//1：初始未开通状态,2:部分开通状态,3完全开通状态

        if((int)$AuthorizeNum <= 0){//已经开通的少于订单数目：未开通状态
            $result = '未开始';
        }

        if( 0 < (int)$AuthorizeNum && $AuthorizeNum < (int)$application['authorization_numeric']){//已经开通的少于订单数目：部分开通状态
            $result = '部分完成';
        }

        //TODO 思考通过租户授权过来的产品如何显示完成状态
        //TODO 思考类似旺财包这样没有数量的产品的完成状态如何表达
        if((int)$AuthorizeNum === (int)$application['authorization_numeric'] ){//完全开通
            if((int)$AuthorizeNum !==0 && (int)$application['authorization_numeric']!==0){
                $result = '全部完成';
            }
        }

        if((int)$AuthorizeNum > (int)$application['authorization_numeric']){//开通数目超过订单数目
            $result = '超额';
        }

        if($application['delivery_rules'] == 1 ||$application['delivery_rules'] == 2){
            $getAuthorizeInfos = OrganizationToAuthorizeRepository::getAuthorizeNumByContractApplicationId($application['contract_application_id']);
            if($getAuthorizeInfos){
                $result = '全部完成';
            }

        }

        return $result;
    }

    /**
     * @param $contractNums
     * @return array|\yii\db\ActiveRecord[]
     */
    private function getAllContracts(array $contractNums)
    {
        if ($contractNums) {
            /** @var MyscrmContractManageService $contractManageService */
            $contractManageService = Yii::createObject(MyscrmContractManageService::className());
            $allContracts = $contractManageService->getContractsByCode($contractNums);
            $allContracts = ArrayHelper::index($allContracts, 'contract_code');
        } else {
            $allContracts = [];
        }

        return $allContracts;
    }

    private function getAllOnShelfApplications()
    {
        $sql ="
        SELECT 
p.`apply_application_id`,
i.`application_id`,
i.`application_name`,
i.`IsQdAdvanced`
 FROM `myscrm_out_stock_allow_product` p

LEFT JOIN `myscrm_application_info` i ON p.`apply_application_id` =i.`application_id`
WHERE i.`is_off_shelf`=0
        ";

        $data = ContractEntity::getDb()->createCommand($sql)->queryAll();

        if(empty($eata)){
            return [];
        }

        return ArrayHelper::index($data, function($item){
            return $item['apply_application_id'].$item['IsQdAdvanced'];
        });
    }


    /**
     * 重设发票类型文本
     */
    private function resetYcType($type) {
        switch ($type) {
            case '1':
            case '5':
                $result = '合同未归档';
                break;
            case '2':
                $result = '开票金额与合同应收金额不相等';
                break;
            case '3':
                $result = '开票名称与签约客户名称不一致';
                break;
            case '4':
                $result = '结算款未支付';
                break;
            case '6':
                $result = '开票名称与付款名称不一致';
                break;
            default:
                $result = '';
                break;
        }

        return $result;
    }

    /**
     * 获取进货合同基本信息
     * @param $contractInfo
     * @param int $contractStatus
     * @return mixed
     */
    public function getAssociateContractParams($contractInfo, $contractStatus = 0) {
        if (!empty($contractInfo)) {
            $contractInfo['sign_id'] = $contractInfo['contract_id'];        //  erp 传过来的会签id
            $contractInfo['contract_status'] = $contractStatus;
            $contractInfo['contract_property_id'] = $this->getContractPropertyIdByName(trim($contractInfo['contract_property']));
            unset($contractInfo['contract_property']);
            $contractInfo['company_id'] = $this->getContractCompanyIdByName(trim($contractInfo['sign_buname']));
            $contractInfo['category_id']          = 'b011f523-fcf2-11e4-bed8-00155d02c832';//合同类别ID 默认为“云客租用服务合同”
            $contractInfo['big_category_id']      = '2ae79470-fcf3-11e4-bed8-00155d02c832';//合同大类ID 默认为“服务合同”
            $contractInfo['littler_category_id']  = '62f81bf4-fcf4-11e4-bed8-00155d02c832';//合同小类ID 默认为“云客租用服务”
            $contractInfo['attribute_name']       = $this->getAttributeNameByName($contractInfo['attribute_name']); //合同属性
            $contractInfo['contract_id']          = StringHelper::uuid();
            $contractInfo['created_by']           = 'AssociateCountersign';
            $contractInfo['modified_by']          = 'AssociateCountersign';
            $contractInfo['income_amount']        = $contractInfo['balance_amount'];    //收入金额 对应页面的 应结算金额
            unset($contractInfo['balance_amount']);
        }
        return $contractInfo;
    }

    /**
     * 通过合同性质名称获取合同性质id
     * @param $contractPropertyName
     * @return array|bool|null|\yii\db\ActiveRecord
     */
    public function getContractPropertyIdByName($contractPropertyName) {
        if (isset($contractPropertyName) && !empty($contractPropertyName)) {
            return ContractPropertyRepository::getPropertyIdByName($contractPropertyName);
        }else{
            return false;
        }
    }

    /**
     * 根据签署公司名称获取签署公司guid
     * @param $sign_buname
     * @return array|bool|null|\yii\db\ActiveRecord
     */
    public function getContractCompanyIdByName($sign_buname) {
        if (isset($sign_buname) && !empty($sign_buname)) {
            return ContractCompanyRepository::getCompanyIdByName($sign_buname);
        }else {
            return false;
        }
    }

    /**
     * 根据合同属性名称 生成对应的合同属性值
     * @param $attribute_name
     * @return string
     */
    public function getAttributeNameByName($attribute_name){
        if (!empty($attribute_name) && isset($attribute_name)) {
            switch ($attribute_name) {
                case '新增':
                    $result = 'true,false,false,false';
                    break;
                case '续签':
                    $result = 'false,false,true,false';
                    break;
                default:
                    $result = 'false,true,false,false';
            }
        }else {
            $result = 'true,false,false,false';
        }
        return $result;
    }

    /**
     *
     */
    public function RevenueRecognitionByDate(){}

    public function RevenueRecognitionByDisposable(){}


    /**
     * 标的物同步至合同系统
     * @param $documents
     * @return bool
     * @throws \yii\db\Exception
     */
    public function doSyncDocument($documents){
        $connection = DocumentEntity::getDb();
        $transaction = $connection->beginTransaction();
        try{
            foreach ($documents as $doc){
                $results[] = DocumentRepository::addDocumentForm($doc,1);
            }
            if(in_array(false, $results)){
                return $this->setAndReturn(__LINE__, '同步失败');
            }else{
                $transaction->commit();
                return true;
            }
        }catch (\Exception $ex){
            $transaction->rollBack();
            Yii::error('标的物同步至合同系统接口保存失败：' . (string)$ex);
            return $this->setAndReturn(__LINE__, '同步失败');
        }
    }


    /**
     * @param $ContractGuid
     * @param $beginTime
     * @param $endTime
     * @return array
     * @throws \yii\db\Exception
     */
    public function getOrdersInfo($ContractGuid,$beginTime,$endTime){
        $all_orders = $this->getOrdersByContractId($ContractGuid,$beginTime,$endTime);
        return $all_orders;
    }


    public function getIllegalErpContract(){
        return ContractManageRepository::getIllegalErpContract();
    }

    /**
     * @param $ContractGuid
     * @param $beginTime
     * @param $endTime
     * @return array
     * @throws \yii\db\Exception
     */
    private function getOrdersByContractId($ContractGuid,$beginTime,$endTime){
        $order_list = ContractManageRepository::getAllOrder($ContractGuid,$beginTime,$endTime);;
        $all_orders = array();
        if(!$order_list){
            return array();
        }
        foreach($order_list as $order){
            $temp = array();
            $temp['OrderGUID'] = $order['ContractApplicationId'];
            $temp['ContractGUID'] = $order['contract_id'];
            $temp['ProductGUID'] = $order['application_info_id']?$order['application_info_id']:$order['ApplicationId'];
            $temp['ProductName'] = $order['application_name']?$order['application_name']:$order['FriendlyName'];
            $temp['Num'] = $order['TotalNum'];
            $temp['RentTime'] = $order['PerformanceAccountingTime'];
            $temp['RentPeriod'] = intval($order['rent_period']);
            $temp['RentStart'] = $order['BeginOn'];
            $temp['RentEnd'] = $order['EndOn'];
            $temp['JsAmount'] = $order['SettlementAmount'];
            $temp['DeliveryGUID'] = $order['DeliveryGUID']?$order['DeliveryGUID']:null;
            $temp['DeliveryCode'] = $order['DeliveryCode'];
            $temp['CreatedOn'] = $order['CreatedOn'];
            $temp['CloudSignType'] = $order['CloudSignType'];
            $all_orders[] = $temp;
        }
        return $all_orders;
    }

    /**
     * 获取授权信息
     * @param $contractId
     * @return array|bool
     */
    private function getContractOrderInfo($contractId)
    {
        $arr = [];
        $contractModel = ContractManageRepository::getContractManageModelByContractId($contractId); // 获取model
        if (empty($contractModel)) { // 合同不存在
            return $this->setAndReturn(ErrorCode::ERR_CONTRACT_NOT_EXISTS);
        }

        ///配置库中获取合同信息 依据合同编号,因此有可能配置库中合同id！=合同库中合同id
        $contractInfos = MyscrmContractRepository::getAllContractByContractNum($contractModel->contract_code); //获取合同表信息

        //一个合同对应多个授权 方便按时间分类
        foreach ($contractInfos as $contractInfo) {
            $authorizeList = OrganizationToAuthorizeRepository::getAuthorizeListByOrganizationId('', $contractInfo->ContractId);
            if (empty($authorizeList)) {
                $authorizeList = [];
            } else {
                $authorize = [];
                foreach ($authorizeList as $key => $value) {
                    $authorize[$key]["beginOn"] = $contractInfo->BeginOn;
                    $authorize[$key]["endOn"] = $contractInfo->EndOn;
                    $authorize[$key]['DeliveryGUID'] = '';
                    $authorize[$key]['DeliveryCode'] = '';
                    $authorize[$key]['establishTime'] = $contractInfo->EstablishTime;
                    $authorize[$key]['performanceAccountingTime'] = $contractInfo->PerformanceAccountingTime;
                    $authorize[$key]['contractType'] = $contractInfo->ContractType;

                    $authorize[$key]['totalNum'] = $value->TotalNum; //授权总数
                    $applicationInfo = MyscrmApplicationRepository::getApplicationByApplicationId($value->ApplicationId);//租户中心产品
                    $applicationInfoAtContractDB = MyscrmContractApplicationService::getApplicationInfoByApplicationId($value->ApplicationId);//所有产品

                    $FriendlyName = $applicationInfo->FriendlyName;
                    $application_name = $applicationInfoAtContractDB['application_name'];

                    //TODO 通过CPI 取appid
                    $contractAndApp = ContractApplicationRepository::getContractApplicationAppId($value->ContractApplicationId);//订单产品信息

                    if(!empty($FriendlyName)) {
                        //坏味道修复
                        $authorize[$key]['applicationName'] = $applicationInfoAtContractDB['application_name'];
                        //坏味道修复
                        if(empty($applicationInfoAtContractDB['application_name'])){
                            $authorize[$key]['applicationName'] = $FriendlyName;
                        }
                    }
                    if(!empty($application_name)){
                        $authorize[$key]['applicationName'] = $application_name;
                    }
                    if(empty($FriendlyName) && empty($application_name)){
                        $authorize[$key]['applicationName'] = '';
                    }
                    if($value->ContractApplicationId){
                        $delivery_info = DeliveryProductRepository::getDeliveryInfoByCAID($value->ContractApplicationId);
                        if($delivery_info){
                            $authorize[$key]['DeliveryGUID'] = $delivery_info['delivery_guid'];
                            $authorize[$key]['DeliveryCode'] = $delivery_info['delivery_code'];
                        }
                    }
                    //TODO 增加 ApplicationId 提供给合同基本信息中产品对比用 by zhoud01 2017-07-20
                    $authorize[$key]['Id'] = $value->Id;//回传给前端的唯一值,判断给那条记录修改 授权主键id
                    $authorize[$key]['ApplicationId'] = $value->ApplicationId;
                    $authorize[$key]['ContractApplicationId'] = $value->ContractApplicationId;
                    $authorize[$key]['contract_code'] = $contractModel->contract_code;
                    $authorize[$key]['ContractId'] = $contractInfo->ContractId;
                    $authorize[$key]['UniqueName'] = $applicationInfo->UniqueName;

                    $authorize[$key]['RentPeriod'] = $contractAndApp->rent_period;

                    $authorize[$key]['StandardAmount'] = $contractAndApp->amount;
                    $authorize[$key]['StandardPrice'] = $contractAndApp->price;
                    $authorize[$key]['SettlementType'] = $contractAndApp->settlement_type;
                    $authorize[$key]['SettlementScale'] = $contractAndApp->settlement_scale;
                    $authorize[$key]['Discount'] = $contractAndApp->discount;
                    $authorize[$key]['RealApplicationId'] = $contractAndApp->application_id;

                    //TODO 在表里增加一个字段标识是修改还是新增 IsModify
                    $authorize[$key]['SettlementAmount'] = $value->SettlementAmount;
                    $authorize[$key]['SignAmount'] = $value->SignAmount;

                    $authorize[$key]['ProductType'] = $value->ProductType;//应该叫产品属性
                    //TODO 如果是自动的产品则取合同属性里的
                }
                $authorizeList = $authorize;
            }

            $arr = array_merge($arr, $authorizeList);

        }
        return $arr;
    }


    public function updateAuthorizeOrderInfo($data){
        $ContractId = $data['ContractId'];
        $order_guid = $data['order_guid'];
        $order_code = $data['order_code'];
        return MyscrmContractRepository::updateOrderInfoByContractId($ContractId,$order_guid,$order_code);
    }


    public function getDirectContract($beginTime,$endTime){
        $data = ContractManageRepository::getDirectContract($beginTime,$endTime);
        return $data;
    }

    public function getDirectContractPayment($beginTime,$endTime){
        $data = ContractManageRepository::getDirectContractPayment($beginTime,$endTime);
        return $data;
    }
}
